Blender V2.61 - r43446

sequencer.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): 
00022  * - Blender Foundation, 2003-2009
00023  * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <stddef.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <math.h>
00037 
00038 #include "MEM_guardedalloc.h"
00039 #include "MEM_CacheLimiterC-Api.h"
00040 
00041 #include "DNA_sequence_types.h"
00042 #include "DNA_scene_types.h"
00043 #include "DNA_anim_types.h"
00044 #include "DNA_object_types.h"
00045 #include "DNA_sound_types.h"
00046 
00047 #include "BLI_math.h"
00048 #include "BLI_fileops.h"
00049 #include "BLI_listbase.h"
00050 #include "BLI_path_util.h"
00051 #include "BLI_string.h"
00052 #include "BLI_threads.h"
00053 #include "BLI_utildefines.h"
00054 
00055 #include "BKE_animsys.h"
00056 #include "BKE_global.h"
00057 #include "BKE_image.h"
00058 #include "BKE_main.h"
00059 #include "BKE_sequencer.h"
00060 #include "BKE_fcurve.h"
00061 #include "BKE_scene.h"
00062 #include "BKE_utildefines.h"
00063 
00064 #include "RNA_access.h"
00065 
00066 #include "RE_pipeline.h"
00067 
00068 #include <pthread.h>
00069 
00070 #include "IMB_imbuf.h"
00071 #include "IMB_imbuf_types.h"
00072 
00073 #include "BKE_context.h"
00074 #include "BKE_sound.h"
00075 
00076 #ifdef WITH_AUDASPACE
00077 #  include "AUD_C-API.h"
00078 #endif
00079 
00080 static ImBuf* seq_render_strip_stack( 
00081     SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
00082 
00083 static ImBuf * seq_render_strip(
00084     SeqRenderData context, Sequence * seq, float cfra);
00085 
00086 static void seq_free_animdata(Scene *scene, Sequence *seq);
00087 
00088 
00089 /* **** XXX ******** */
00090 #define SELECT 1
00091 ListBase seqbase_clipboard;
00092 int seqbase_clipboard_frame;
00093 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
00094 
00095 
00096 void printf_strip(Sequence *seq)
00097 {
00098     fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
00099             seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
00100     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));
00101 }
00102 
00103 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
00104 {
00105     Sequence *iseq;
00106     for(iseq= seqbase->first; iseq; iseq= iseq->next) {
00107         if(seq_recursive_apply(iseq, apply_func, arg) == -1)
00108             return -1; /* bail out */
00109     }
00110     return 1;
00111 }
00112 
00113 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
00114 {
00115     int ret= apply_func(seq, arg);
00116 
00117     if(ret == -1)
00118         return -1;  /* bail out */
00119 
00120     if(ret && seq->seqbase.first)
00121         ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
00122 
00123     return ret;
00124 }
00125 
00126 /* **********************************************************************
00127    alloc / free functions
00128    ********************************************************************** */
00129 
00130 
00131 
00132 void new_tstripdata(Sequence *seq)
00133 {
00134     if(seq->strip) {
00135         seq->strip->len= seq->len;
00136     }
00137 }
00138 
00139 
00140 /* free */
00141 
00142 static void free_proxy_seq(Sequence *seq)
00143 {
00144     if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) {
00145         IMB_free_anim(seq->strip->proxy->anim);
00146         seq->strip->proxy->anim = NULL;
00147     }
00148 }
00149 
00150 void seq_free_strip(Strip *strip)
00151 {
00152     strip->us--;
00153     if(strip->us>0) return;
00154     if(strip->us<0) {
00155         printf("error: negative users in strip\n");
00156         return;
00157     }
00158 
00159     if (strip->stripdata) {
00160         MEM_freeN(strip->stripdata);
00161     }
00162 
00163     if (strip->proxy) {
00164         if (strip->proxy->anim) {
00165             IMB_free_anim(strip->proxy->anim);
00166         }
00167 
00168         MEM_freeN(strip->proxy);
00169     }
00170     if (strip->crop) {
00171         MEM_freeN(strip->crop);
00172     }
00173     if (strip->transform) {
00174         MEM_freeN(strip->transform);
00175     }
00176     if (strip->color_balance) {
00177         MEM_freeN(strip->color_balance);
00178     }
00179 
00180     MEM_freeN(strip);
00181 }
00182 
00183 void seq_free_sequence(Scene *scene, Sequence *seq)
00184 {
00185     if(seq->strip) seq_free_strip(seq->strip);
00186 
00187     if(seq->anim) IMB_free_anim(seq->anim);
00188 
00189     if (seq->type & SEQ_EFFECT) {
00190         struct SeqEffectHandle sh = get_sequence_effect(seq);
00191 
00192         sh.free(seq);
00193     }
00194 
00195     if(seq->sound) {
00196         ((ID *)seq->sound)->us--; 
00197     }
00198 
00199     /* clipboard has no scene and will never have a sound handle or be active */
00200     if(scene) {
00201         Editing *ed = scene->ed;
00202 
00203         if (ed->act_seq==seq)
00204             ed->act_seq= NULL;
00205 
00206         if(seq->scene_sound && ELEM(seq->type, SEQ_SOUND, SEQ_SCENE))
00207             sound_remove_scene_sound(scene, seq->scene_sound);
00208 
00209         seq_free_animdata(scene, seq);
00210     }
00211 
00212     MEM_freeN(seq);
00213 }
00214 
00215 void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
00216 {
00217     Sequence *iseq;
00218 
00219     for(iseq= seq->seqbase.first; iseq; iseq= iseq->next) {
00220         seq_free_sequence_recurse(scene, iseq);
00221     }
00222 
00223     seq_free_sequence(scene, seq);
00224 }
00225 
00226 
00227 Editing *seq_give_editing(Scene *scene, int alloc)
00228 {
00229     if (scene->ed == NULL && alloc) {
00230         Editing *ed;
00231 
00232         ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq");
00233         ed->seqbasep= &ed->seqbase;
00234     }
00235     return scene->ed;
00236 }
00237 
00238 static void seq_free_clipboard_recursive(Sequence *seq_parent)
00239 {
00240     Sequence *seq, *nseq;
00241 
00242     for(seq= seq_parent->seqbase.first; seq; seq= nseq) {
00243         nseq= seq->next;
00244         seq_free_clipboard_recursive(seq);
00245     }
00246 
00247     seq_free_sequence(NULL, seq_parent);
00248 }
00249 
00250 void seq_free_clipboard(void)
00251 {
00252     Sequence *seq, *nseq;
00253 
00254     for(seq= seqbase_clipboard.first; seq; seq= nseq) {
00255         nseq= seq->next;
00256         seq_free_clipboard_recursive(seq);
00257     }
00258     seqbase_clipboard.first= seqbase_clipboard.last= NULL;
00259 }
00260 
00261 void seq_free_editing(Scene *scene)
00262 {
00263     Editing *ed = scene->ed;
00264     MetaStack *ms;
00265     Sequence *seq;
00266 
00267     if(ed==NULL)
00268         return;
00269 
00270     SEQ_BEGIN(ed, seq) {
00271         seq_free_sequence(scene, seq);
00272     }
00273     SEQ_END
00274 
00275     while((ms= ed->metastack.first)) {
00276         BLI_remlink(&ed->metastack, ms);
00277         MEM_freeN(ms);
00278     }
00279 
00280     MEM_freeN(ed);
00281 }
00282 
00283 /* **********************************************************************
00284    * sequencer pipeline functions
00285    ********************************************************************** */
00286 
00287 SeqRenderData seq_new_render_data(
00288     struct Main * bmain, struct Scene * scene,
00289     int rectx, int recty, int preview_render_size)
00290 {
00291     SeqRenderData rval;
00292 
00293     rval.bmain = bmain;
00294     rval.scene = scene;
00295     rval.rectx = rectx;
00296     rval.recty = recty;
00297     rval.preview_render_size = preview_render_size;
00298     rval.motion_blur_samples = 0;
00299     rval.motion_blur_shutter = 0;
00300 
00301     return rval;
00302 }
00303 
00304 int seq_cmp_render_data(const SeqRenderData * a, const SeqRenderData * b)
00305 {
00306     if (a->preview_render_size < b->preview_render_size) {
00307         return -1;
00308     }
00309     if (a->preview_render_size > b->preview_render_size) {
00310         return 1;
00311     }
00312     
00313     if (a->rectx < b->rectx) {
00314         return -1;
00315     }
00316     if (a->rectx > b->rectx) {
00317         return 1;
00318     }
00319 
00320     if (a->recty < b->recty) {
00321         return -1;
00322     }
00323     if (a->recty > b->recty) {
00324         return 1;
00325     }
00326 
00327     if (a->bmain < b->bmain) {
00328         return -1;
00329     }
00330     if (a->bmain > b->bmain) {
00331         return 1;
00332     }
00333 
00334     if (a->scene < b->scene) {
00335         return -1;
00336     }
00337     if (a->scene > b->scene) {
00338         return 1;
00339     }
00340 
00341     if (a->motion_blur_shutter < b->motion_blur_shutter) {
00342         return -1;
00343     }
00344     if (a->motion_blur_shutter > b->motion_blur_shutter) {
00345         return 1;
00346     }
00347 
00348     if (a->motion_blur_samples < b->motion_blur_samples) {
00349         return -1;
00350     }
00351     if (a->motion_blur_samples > b->motion_blur_samples) {
00352         return 1;
00353     }
00354 
00355     return 0;
00356 }
00357 
00358 unsigned int seq_hash_render_data(const SeqRenderData * a)
00359 {
00360     unsigned int rval = a->rectx + a->recty;
00361 
00362     rval ^= a->preview_render_size;
00363     rval ^= ((intptr_t) a->bmain) << 6;
00364     rval ^= ((intptr_t) a->scene) << 6;
00365     rval ^= (int) (a->motion_blur_shutter * 100.0f) << 10;
00366     rval ^= a->motion_blur_samples << 24;
00367     
00368     return rval;
00369 }
00370 
00371 /* ************************* iterator ************************** */
00372 /* *************** (replaces old WHILE_SEQ) ********************* */
00373 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */
00374 
00375 /* sequence strip iterator:
00376  * - builds a full array, recursively into meta strips */
00377 
00378 static void seq_count(ListBase *seqbase, int *tot)
00379 {
00380     Sequence *seq;
00381 
00382     for(seq=seqbase->first; seq; seq=seq->next) {
00383         (*tot)++;
00384 
00385         if(seq->seqbase.first)
00386             seq_count(&seq->seqbase, tot);
00387     }
00388 }
00389 
00390 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth)
00391 {
00392     Sequence *seq;
00393 
00394     for(seq=seqbase->first; seq; seq=seq->next) {
00395         seq->depth= depth;
00396 
00397         if(seq->seqbase.first)
00398             seq_build_array(&seq->seqbase, array, depth+1);
00399 
00400         **array= seq;
00401         (*array)++;
00402     }
00403 }
00404 
00405 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer)
00406 {
00407     Sequence **array;
00408 
00409     *seqarray= NULL;
00410     *tot= 0;
00411 
00412     if(ed == NULL)
00413         return;
00414 
00415     if(use_pointer)
00416         seq_count(ed->seqbasep, tot);
00417     else
00418         seq_count(&ed->seqbase, tot);
00419 
00420     if(*tot == 0)
00421         return;
00422 
00423     *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray");
00424     if(use_pointer)
00425         seq_build_array(ed->seqbasep, &array, 0);
00426     else
00427         seq_build_array(&ed->seqbase, &array, 0);
00428 }
00429 
00430 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer)
00431 {
00432     memset(iter, 0, sizeof(*iter));
00433     seq_array(ed, &iter->array, &iter->tot, use_pointer);
00434 
00435     if(iter->tot) {
00436         iter->cur= 0;
00437         iter->seq= iter->array[iter->cur];
00438         iter->valid= 1;
00439     }
00440 }
00441 
00442 void seq_next(SeqIterator *iter)
00443 {
00444     if(++iter->cur < iter->tot)
00445         iter->seq= iter->array[iter->cur];
00446     else
00447         iter->valid= 0;
00448 }
00449 
00450 void seq_end(SeqIterator *iter)
00451 {
00452     if(iter->array)
00453         MEM_freeN(iter->array);
00454 
00455     iter->valid= 0;
00456 }
00457 
00458 /*
00459   **********************************************************************
00460   * build_seqar
00461   **********************************************************************
00462   * Build a complete array of _all_ sequencies (including those
00463   * in metastrips!)
00464   **********************************************************************
00465 */
00466 
00467 static void do_seq_count_cb(ListBase *seqbase, int *totseq,
00468                 int (*test_func)(Sequence * seq))
00469 {
00470     Sequence *seq;
00471 
00472     seq= seqbase->first;
00473     while(seq) {
00474         int test = test_func(seq);
00475         if (test & BUILD_SEQAR_COUNT_CURRENT) {
00476             (*totseq)++;
00477         }
00478         if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
00479             do_seq_count_cb(&seq->seqbase, totseq, test_func);
00480         }
00481         seq= seq->next;
00482     }
00483 }
00484 
00485 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
00486                   int (*test_func)(Sequence * seq))
00487 {
00488     Sequence *seq;
00489 
00490     seq= seqbase->first;
00491     while(seq) {
00492         int test = test_func(seq);
00493         seq->depth= depth;
00494 
00495         if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
00496             do_build_seqar_cb(&seq->seqbase, seqar, depth+1, test_func);
00497         }
00498         if (test & BUILD_SEQAR_COUNT_CURRENT) {
00499             **seqar= seq;
00500             (*seqar)++;
00501         }
00502         seq= seq->next;
00503     }
00504 }
00505 
00506 void build_seqar_cb(ListBase *seqbase, Sequence  ***seqar, int *totseq,
00507             int (*test_func)(Sequence * seq))
00508 {
00509     Sequence **tseqar;
00510 
00511     *totseq= 0;
00512     do_seq_count_cb(seqbase, totseq, test_func);
00513 
00514     if(*totseq==0) {
00515         *seqar= NULL;
00516         return;
00517     }
00518     *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
00519     tseqar= *seqar;
00520 
00521     do_build_seqar_cb(seqbase, seqar, 0, test_func);
00522     *seqar= tseqar;
00523 }
00524 
00525 
00526 void calc_sequence_disp(Scene *scene, Sequence *seq)
00527 {
00528     if(seq->startofs && seq->startstill) seq->startstill= 0;
00529     if(seq->endofs && seq->endstill) seq->endstill= 0;
00530     
00531     seq->startdisp= seq->start + seq->startofs - seq->startstill;
00532     seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
00533     
00534     seq->handsize= 10.0;    /* 10 frames */
00535     if( seq->enddisp-seq->startdisp < 10 ) {
00536         seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
00537     }
00538     else if(seq->enddisp-seq->startdisp > 250) {
00539         seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
00540     }
00541 
00542     seq_update_sound_bounds(scene, seq);
00543 }
00544 
00545 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
00546 {
00547     Sequence *seq;
00548 
00549     /* for sound we go over full meta tree to update bounds of the sound strips,
00550        since sound is played outside of evaluating the imbufs, */
00551     for(seq=metaseq->seqbase.first; seq; seq=seq->next) {
00552         if(seq->type == SEQ_META) {
00553             seq_update_sound_bounds_recursive(scene, seq);
00554         }
00555         else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
00556             if(seq->scene_sound) {
00557                 int startofs = seq->startofs;
00558                 int endofs = seq->endofs;
00559                 if(seq->startofs + seq->start < metaseq->start + metaseq->startofs)
00560                     startofs = metaseq->start + metaseq->startofs - seq->start;
00561 
00562                 if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
00563                     endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
00564                 sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs);
00565             }
00566         }
00567     }
00568 }
00569 
00570 void calc_sequence(Scene *scene, Sequence *seq)
00571 {
00572     Sequence *seqm;
00573     int min, max;
00574 
00575     /* check all metas recursively */
00576     seqm= seq->seqbase.first;
00577     while(seqm) {
00578         if(seqm->seqbase.first) calc_sequence(scene, seqm);
00579         seqm= seqm->next;
00580     }
00581 
00582     /* effects and meta: automatic start and end */
00583 
00584     if(seq->type & SEQ_EFFECT) {
00585         /* pointers */
00586         if(seq->seq2==NULL) seq->seq2= seq->seq1;
00587         if(seq->seq3==NULL) seq->seq3= seq->seq1;
00588 
00589         /* effecten go from seq1 -> seq2: test */
00590 
00591         /* we take the largest start and smallest end */
00592 
00593         // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
00594         // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
00595 
00596         if (seq->seq1) {
00597             /* XXX These resets should not be necessary, but users used to be able to
00598              *     edit effect's length, leading to strange results. See #29190. */
00599             seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
00600             seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
00601             seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
00602             /* we cant help if strips don't overlap, it wont give useful results.
00603              * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
00604             if(seq->enddisp < seq->startdisp) {
00605                 /* simple start/end swap */
00606                 seq->start= seq->enddisp;
00607                 seq->enddisp = seq->startdisp;
00608                 seq->startdisp= seq->start;
00609                 seq->flag |= SEQ_INVALID_EFFECT;
00610             }
00611             else {
00612                 seq->flag &= ~SEQ_INVALID_EFFECT;
00613             }
00614 
00615             seq->len= seq->enddisp - seq->startdisp;
00616         }
00617         else {
00618             calc_sequence_disp(scene, seq);
00619         }
00620 
00621         if(seq->strip && seq->len!=seq->strip->len) {
00622             new_tstripdata(seq);
00623         }
00624 
00625     }
00626     else {
00627         if(seq->type==SEQ_META) {
00628             seqm= seq->seqbase.first;
00629             if(seqm) {
00630                 min=  MAXFRAME * 2;
00631                 max= -MAXFRAME * 2;
00632                 while(seqm) {
00633                     if(seqm->startdisp < min) min= seqm->startdisp;
00634                     if(seqm->enddisp > max) max= seqm->enddisp;
00635                     seqm= seqm->next;
00636                 }
00637                 seq->start= min + seq->anim_startofs;
00638                 seq->len = max-min;
00639                 seq->len -= seq->anim_startofs;
00640                 seq->len -= seq->anim_endofs;
00641 
00642                 if(seq->strip && seq->len!=seq->strip->len) {
00643                     new_tstripdata(seq);
00644                 }
00645             }
00646             seq_update_sound_bounds_recursive(scene, seq);
00647         }
00648         calc_sequence_disp(scene, seq);
00649     }
00650 }
00651 
00652 /* note: caller should run calc_sequence(scene, seq) after */
00653 void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
00654 {
00655     char str[FILE_MAX];
00656     int prev_startdisp=0, prev_enddisp=0;
00657     /* note: dont rename the strip, will break animation curves */
00658 
00659     if (ELEM5(seq->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_SCENE, SEQ_META)==0) {
00660         return;
00661     }
00662 
00663     if(lock_range) {
00664         /* keep so we dont have to move the actual start and end points (only the data) */
00665         calc_sequence_disp(scene, seq);
00666         prev_startdisp= seq->startdisp;
00667         prev_enddisp= seq->enddisp;
00668     }
00669 
00670 
00671     new_tstripdata(seq);
00672 
00673     if (ELEM3(seq->type, SEQ_SCENE, SEQ_META, SEQ_IMAGE)==0) {
00674         BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
00675         BLI_path_abs(str, G.main->name);
00676     }
00677 
00678     switch(seq->type) {
00679     case SEQ_IMAGE:
00680     {
00681         /* Hack? */
00682         size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
00683 
00684         seq->len = olen;
00685         seq->len -= seq->anim_startofs;
00686         seq->len -= seq->anim_endofs;
00687         if (seq->len < 0) {
00688             seq->len = 0;
00689         }
00690         seq->strip->len = seq->len;
00691         break;
00692     }
00693     case SEQ_MOVIE:
00694         if(seq->anim) IMB_free_anim(seq->anim);
00695         seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
00696 
00697         if (!seq->anim) {
00698             return;
00699         }
00700     
00701         seq->len = IMB_anim_get_duration(seq->anim,
00702                          seq->strip->proxy ?
00703                          seq->strip->proxy->tc :
00704                          IMB_TC_RECORD_RUN);
00705         
00706         seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
00707 
00708         seq->len -= seq->anim_startofs;
00709         seq->len -= seq->anim_endofs;
00710         if (seq->len < 0) {
00711             seq->len = 0;
00712         }
00713         seq->strip->len = seq->len;
00714         break;
00715     case SEQ_SOUND:
00716 #ifdef WITH_AUDASPACE
00717         if(!seq->sound)
00718             return;
00719         seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS);
00720         seq->len -= seq->anim_startofs;
00721         seq->len -= seq->anim_endofs;
00722         if (seq->len < 0) {
00723             seq->len = 0;
00724         }
00725         seq->strip->len = seq->len;
00726 #else
00727         return;
00728 #endif
00729         break;
00730     case SEQ_SCENE:
00731     {
00732         /* 'seq->scenenr' should be replaced with something more reliable */
00733         Scene * sce = G.main->scene.first;
00734         int nr = 1;
00735         
00736         while(sce) {
00737             if(nr == seq->scenenr) {
00738                 break;
00739             }
00740             nr++;
00741             sce= sce->id.next;
00742         }
00743 
00744         if (sce) {
00745             seq->scene = sce;
00746         }
00747 
00748         seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
00749         seq->len -= seq->anim_startofs;
00750         seq->len -= seq->anim_endofs;
00751         if (seq->len < 0) {
00752             seq->len = 0;
00753         }
00754         seq->strip->len = seq->len;
00755         break;
00756     }
00757     }
00758 
00759     free_proxy_seq(seq);
00760 
00761     if(lock_range) {
00762         seq_tx_set_final_left(seq, prev_startdisp);
00763         seq_tx_set_final_right(seq, prev_enddisp);
00764         seq_single_fix(seq);
00765     }
00766     
00767     calc_sequence(scene, seq);
00768 }
00769 
00770 void sort_seq(Scene *scene)
00771 {
00772     /* all strips together per kind, and in order of y location ("machine") */
00773     ListBase seqbase, effbase;
00774     Editing *ed= seq_give_editing(scene, FALSE);
00775     Sequence *seq, *seqt;
00776 
00777     
00778     if(ed==NULL) return;
00779 
00780     seqbase.first= seqbase.last= NULL;
00781     effbase.first= effbase.last= NULL;
00782 
00783     while( (seq= ed->seqbasep->first) ) {
00784         BLI_remlink(ed->seqbasep, seq);
00785 
00786         if(seq->type & SEQ_EFFECT) {
00787             seqt= effbase.first;
00788             while(seqt) {
00789                 if(seqt->machine>=seq->machine) {
00790                     BLI_insertlinkbefore(&effbase, seqt, seq);
00791                     break;
00792                 }
00793                 seqt= seqt->next;
00794             }
00795             if(seqt==NULL) BLI_addtail(&effbase, seq);
00796         }
00797         else {
00798             seqt= seqbase.first;
00799             while(seqt) {
00800                 if(seqt->machine>=seq->machine) {
00801                     BLI_insertlinkbefore(&seqbase, seqt, seq);
00802                     break;
00803                 }
00804                 seqt= seqt->next;
00805             }
00806             if(seqt==NULL) BLI_addtail(&seqbase, seq);
00807         }
00808     }
00809 
00810     BLI_movelisttolist(&seqbase, &effbase);
00811     *(ed->seqbasep)= seqbase;
00812 }
00813 
00814 
00815 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt)
00816 {
00817     if(seq->scene==(Scene *)arg_pt)
00818         seq->scene= NULL;
00819     return 1;
00820 }
00821 
00822 void clear_scene_in_allseqs(Main *bmain, Scene *scene)
00823 {
00824     Scene *scene_iter;
00825 
00826     /* when a scene is deleted: test all seqs */
00827     for(scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) {
00828         if(scene_iter != scene && scene_iter->ed) {
00829             seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
00830         }
00831     }
00832 }
00833 
00834 typedef struct SeqUniqueInfo {
00835     Sequence *seq;
00836     char name_src[SEQ_NAME_MAXSTR];
00837     char name_dest[SEQ_NAME_MAXSTR];
00838     int count;
00839     int match;
00840 } SeqUniqueInfo;
00841 
00842 /*
00843 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
00844 {
00845     BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
00846 }*/
00847 
00848 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
00849 {
00850     Sequence *seq;
00851     for(seq=seqbasep->first; seq; seq= seq->next) {
00852         if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
00853             /* SEQ_NAME_MAXSTR - 2 for prefix, -1 for \0, -4 for the number */
00854             BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.59s.%03d",  sui->name_src, sui->count++);
00855             sui->match= 1; /* be sure to re-scan */
00856         }
00857     }
00858 }
00859 
00860 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
00861 {
00862     if(seq->seqbase.first)
00863         seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt);
00864     return 1;
00865 }
00866 
00867 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
00868 {
00869     SeqUniqueInfo sui;
00870     char *dot;
00871     sui.seq= seq;
00872     BLI_strncpy(sui.name_src, seq->name+2, sizeof(sui.name_src));
00873     BLI_strncpy(sui.name_dest, seq->name+2, sizeof(sui.name_dest));
00874 
00875     sui.count= 1;
00876     sui.match= 1; /* assume the worst to start the loop */
00877 
00878     /* Strip off the suffix */
00879     if ((dot=strrchr(sui.name_src, '.'))) {
00880         *dot= '\0';
00881         dot++;
00882 
00883         if(*dot)
00884             sui.count= atoi(dot) + 1;
00885     }
00886 
00887     while(sui.match) {
00888         sui.match= 0;
00889         seqbase_unique_name(seqbasep, &sui);
00890         seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui);
00891     }
00892 
00893     BLI_strncpy(seq->name+2, sui.name_dest, sizeof(seq->name)-2);
00894 }
00895 
00896 static const char *give_seqname_by_type(int type)
00897 {
00898     switch(type) {
00899     case SEQ_META:       return "Meta";
00900     case SEQ_IMAGE:      return "Image";
00901     case SEQ_SCENE:      return "Scene";
00902     case SEQ_MOVIE:      return "Movie";
00903     case SEQ_SOUND:      return "Audio";
00904     case SEQ_CROSS:      return "Cross";
00905     case SEQ_GAMCROSS:   return "Gamma Cross";
00906     case SEQ_ADD:        return "Add";
00907     case SEQ_SUB:        return "Sub";
00908     case SEQ_MUL:        return "Mul";
00909     case SEQ_ALPHAOVER:  return "Alpha Over";
00910     case SEQ_ALPHAUNDER: return "Alpha Under";
00911     case SEQ_OVERDROP:   return "Over Drop";
00912     case SEQ_WIPE:       return "Wipe";
00913     case SEQ_GLOW:       return "Glow";
00914     case SEQ_TRANSFORM:  return "Transform";
00915     case SEQ_COLOR:      return "Color";
00916     case SEQ_MULTICAM:   return "Multicam";
00917     case SEQ_ADJUSTMENT: return "Adjustment";
00918     case SEQ_SPEED:      return "Speed";
00919     default:
00920         return NULL;
00921     }
00922 }
00923 
00924 const char *give_seqname(Sequence *seq)
00925 {
00926     const char *name = give_seqname_by_type(seq->type);
00927 
00928     if (!name) {
00929         if(seq->type<SEQ_EFFECT) {
00930             return seq->strip->dir;
00931         } else if(seq->type==SEQ_PLUGIN) {
00932             if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
00933                seq->plugin && seq->plugin->doit) {
00934                 return seq->plugin->pname;
00935             } else {
00936                 return "Plugin";
00937             }
00938         } else {
00939             return "Effect";
00940         }
00941     }
00942     return name;
00943 }
00944 
00945 /* ***************** DO THE SEQUENCE ***************** */
00946 
00947 static void make_black_ibuf(ImBuf *ibuf)
00948 {
00949     unsigned int *rect;
00950     float *rect_float;
00951     int tot;
00952 
00953     if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return;
00954 
00955     tot= ibuf->x*ibuf->y;
00956 
00957     rect= ibuf->rect;
00958     rect_float = ibuf->rect_float;
00959 
00960     if (rect) {
00961         memset(rect,       0, tot * sizeof(char) * 4);
00962     }
00963 
00964     if (rect_float) {
00965         memset(rect_float, 0, tot * sizeof(float) * 4);
00966     }
00967 }
00968 
00969 static void multibuf(ImBuf *ibuf, float fmul)
00970 {
00971     char *rt;
00972     float *rt_float;
00973 
00974     int a, mul, icol;
00975 
00976     mul= (int)(256.0f * fmul);
00977     rt= (char *)ibuf->rect;
00978     rt_float = ibuf->rect_float;
00979 
00980     if (rt) {
00981         a= ibuf->x*ibuf->y;
00982         while(a--) {
00983 
00984             icol= (mul*rt[0])>>8;
00985             if(icol>254) rt[0]= 255; else rt[0]= icol;
00986             icol= (mul*rt[1])>>8;
00987             if(icol>254) rt[1]= 255; else rt[1]= icol;
00988             icol= (mul*rt[2])>>8;
00989             if(icol>254) rt[2]= 255; else rt[2]= icol;
00990             icol= (mul*rt[3])>>8;
00991             if(icol>254) rt[3]= 255; else rt[3]= icol;
00992             
00993             rt+= 4;
00994         }
00995     }
00996     if (rt_float) {
00997         a= ibuf->x*ibuf->y;
00998         while(a--) {
00999             rt_float[0] *= fmul;
01000             rt_float[1] *= fmul;
01001             rt_float[2] *= fmul;
01002             rt_float[3] *= fmul;
01003             
01004             rt_float += 4;
01005         }
01006     }
01007 }
01008 
01009 static float give_stripelem_index(Sequence *seq, float cfra)
01010 {
01011     float nr;
01012     int sta = seq->start;
01013     int end = seq->start+seq->len-1;
01014 
01015     if (seq->type & SEQ_EFFECT) {
01016         end = seq->enddisp;
01017     } 
01018 
01019     if(end < sta) {
01020         return -1;
01021     }
01022 
01023     if(seq->flag&SEQ_REVERSE_FRAMES) {  
01024         /*reverse frame in this sequence */
01025         if(cfra <= sta) nr= end - sta;
01026         else if(cfra >= end) nr= 0;
01027         else nr= end - cfra;
01028     } else {
01029         if(cfra <= sta) nr= 0;
01030         else if(cfra >= end) nr= end - sta;
01031         else nr= cfra - sta;
01032     }
01033     
01034     if (seq->strobe < 1.0f) seq->strobe = 1.0f;
01035     
01036     if (seq->strobe > 1.0f) {
01037         nr -= fmodf((double)nr, (double)seq->strobe);
01038     }
01039 
01040     return nr;
01041 }
01042 
01043 StripElem *give_stripelem(Sequence *seq, int cfra)
01044 {
01045     StripElem *se= seq->strip->stripdata;
01046 
01047     if(seq->type == SEQ_IMAGE) { /* only 
01048                     IMAGE strips use the whole array,
01049                     MOVIE strips use only 
01050                     the first element, all other strips
01051                     don't use this... */
01052         int nr = (int) give_stripelem_index(seq, cfra);
01053 
01054         if (nr == -1 || se == NULL) return NULL;
01055     
01056         se += nr + seq->anim_startofs;
01057     }
01058     return se;
01059 }
01060 
01061 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra)
01062 {
01063     Sequence *seq;
01064     int totseq=0;
01065 
01066     memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
01067 
01068     seq= seqbase->first;
01069     while(seq) {
01070         if(seq->startdisp <=cfra && seq->enddisp > cfra) {
01071             seq_arr[seq->machine]= seq;
01072             totseq++;
01073         }
01074         seq= seq->next;
01075     }
01076 
01077     return totseq;
01078 }
01079 
01080 int evaluate_seq_frame(Scene *scene, int cfra)
01081 {
01082     Editing *ed= seq_give_editing(scene, FALSE);
01083     Sequence *seq_arr[MAXSEQ+1];
01084 
01085     if(ed==NULL) return 0;
01086     return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra);
01087 }
01088 
01089 static int video_seq_is_rendered(Sequence * seq)
01090 {
01091     return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_SOUND);
01092 }
01093 
01094 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
01095 {
01096     Sequence *seq_arr[MAXSEQ+1];
01097     int b = chanshown;
01098     int cnt = 0;
01099 
01100     if (b > MAXSEQ) {
01101         return 0;
01102     }
01103 
01104     if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
01105         if (b == 0) {
01106             b = MAXSEQ;
01107         }
01108         for (; b > 0; b--) {
01109             if (video_seq_is_rendered(seq_arr[b])) {
01110                 break;
01111             }
01112         }
01113     }
01114     
01115     chanshown = b;
01116 
01117     for (;b > 0; b--) {
01118         if (video_seq_is_rendered(seq_arr[b])) {
01119             if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
01120                 break;
01121             }
01122         }
01123     }
01124 
01125     for (;b <= chanshown && b >= 0; b++) {
01126         if (video_seq_is_rendered(seq_arr[b])) {
01127             seq_arr_out[cnt++] = seq_arr[b];
01128         }
01129     }
01130 
01131     return cnt;
01132 }
01133 
01134 
01135 /* **********************************************************************
01136    proxy management
01137    ********************************************************************** */
01138 
01139 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
01140 
01141 static IMB_Proxy_Size seq_rendersize_to_proxysize(int size)
01142 {
01143     if (size >= 100) {
01144         return IMB_PROXY_NONE;
01145     }
01146     if (size >= 99) {
01147         return IMB_PROXY_100;
01148     }
01149     if (size >= 75) {
01150         return IMB_PROXY_75;
01151     }
01152     if (size >= 50) {
01153         return IMB_PROXY_50;
01154     }
01155     return IMB_PROXY_25;
01156 }
01157 
01158 static void seq_open_anim_file(Sequence * seq)
01159 {
01160     char name[FILE_MAX];
01161     StripProxy * proxy;
01162 
01163     if(seq->anim != NULL) {
01164         return;
01165     }
01166 
01167     BLI_join_dirfile(name, sizeof(name),
01168                      seq->strip->dir, seq->strip->stripdata->name);
01169     BLI_path_abs(name, G.main->name);
01170     
01171     seq->anim = openanim(name, IB_rect |
01172                          ((seq->flag & SEQ_FILTERY) ?
01173                               IB_animdeinterlace : 0), seq->streamindex);
01174 
01175     if (seq->anim == NULL) {
01176         return;
01177     }
01178 
01179     proxy = seq->strip->proxy;
01180 
01181     if (proxy == NULL) {
01182         return;
01183     }
01184 
01185     if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
01186         IMB_anim_set_index_dir(seq->anim, seq->strip->proxy->dir);
01187     }
01188 }
01189 
01190 
01191 static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra, char * name)
01192 {
01193     int frameno;
01194     char dir[PROXY_MAXFILE];
01195     int render_size = context.preview_render_size;
01196 
01197     if (!seq->strip->proxy) {
01198         return FALSE;
01199     }
01200 
01201     /* MOVIE tracks (only exception: custom files) are now handled 
01202        internally by ImBuf module for various reasons: proper time code 
01203        support, quicker index build, using one file instead 
01204        of a full directory of jpeg files, etc. Trying to support old
01205        and new method at once could lead to funny effects, if people
01206        have both, a directory full of jpeg files and proxy avis, so
01207        sorry folks, please rebuild your proxies... */
01208 
01209     if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR|SEQ_USE_PROXY_CUSTOM_FILE)) {
01210         BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
01211     } else if (seq->type == SEQ_IMAGE) {
01212         BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
01213     } else {
01214         return FALSE;
01215     }
01216 
01217     if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
01218         BLI_join_dirfile(name, PROXY_MAXFILE,
01219                          dir, seq->strip->proxy->file);
01220         BLI_path_abs(name, G.main->name);
01221 
01222         return TRUE;
01223     }
01224 
01225     /* dirty hack to distinguish 100% render size from PROXY_100 */
01226     if (render_size == 99) {
01227         render_size = 100;
01228     }
01229 
01230     /* generate a separate proxy directory for each preview size */
01231 
01232     if (seq->type == SEQ_IMAGE) {
01233         BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
01234                      context.preview_render_size,
01235                      give_stripelem(seq, cfra)->name);
01236         frameno = 1;
01237     } else {
01238         frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
01239         BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir, 
01240                      context.preview_render_size);
01241     }
01242 
01243     BLI_path_abs(name, G.main->name);
01244     BLI_path_frame(name, frameno, 0);
01245 
01246     strcat(name, ".jpg");
01247 
01248     return TRUE;
01249 }
01250 
01251 static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int cfra)
01252 {
01253     char name[PROXY_MAXFILE];
01254     IMB_Proxy_Size psize = seq_rendersize_to_proxysize(
01255         context.preview_render_size);
01256     int size_flags;
01257 
01258     if (!(seq->flag & SEQ_USE_PROXY)) {
01259         return NULL;
01260     }
01261 
01262     size_flags = seq->strip->proxy->build_size_flags;
01263 
01264     /* only use proxies, if they are enabled (even if present!) */
01265     if (psize == IMB_PROXY_NONE || ((size_flags & psize) != psize)) {
01266         return NULL;
01267     }
01268 
01269     if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
01270         int frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs;
01271         if (seq->strip->proxy->anim == NULL) {
01272             if (seq_proxy_get_fname(context, seq, cfra, name)==0) {
01273                 return NULL;
01274             }
01275  
01276             seq->strip->proxy->anim = openanim(name, IB_rect, 0);
01277         }
01278         if (seq->strip->proxy->anim==NULL) {
01279             return NULL;
01280         }
01281  
01282         seq_open_anim_file(seq);
01283 
01284         frameno = IMB_anim_index_get_frame_index(
01285             seq->anim, seq->strip->proxy->tc, frameno);
01286 
01287         return IMB_anim_absolute(seq->strip->proxy->anim, frameno,
01288                      IMB_TC_NONE, IMB_PROXY_NONE);
01289     }
01290  
01291     if (seq_proxy_get_fname(context, seq, cfra, name) == 0) {
01292         return NULL;
01293     }
01294 
01295     if (BLI_exists(name)) {
01296         return IMB_loadiffname(name, IB_rect);
01297     } else {
01298         return NULL;
01299     }
01300 }
01301 
01302 static void seq_proxy_build_frame(SeqRenderData context,
01303                   Sequence* seq, int cfra,
01304                   int proxy_render_size)
01305 {
01306     char name[PROXY_MAXFILE];
01307     int quality;
01308     int rectx, recty;
01309     int ok;
01310     struct ImBuf * ibuf;
01311 
01312     if (!seq_proxy_get_fname(context, seq, cfra, name)) {
01313         return;
01314     }
01315 
01316     ibuf = seq_render_strip(context, seq, cfra);
01317 
01318     rectx = (proxy_render_size * context.scene->r.xsch) / 100;
01319     recty = (proxy_render_size * context.scene->r.ysch) / 100;
01320 
01321     if (ibuf->x != rectx || ibuf->y != recty) {
01322         IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
01323     }
01324 
01325     /* depth = 32 is intentionally left in, otherwise ALPHA channels
01326        won't work... */
01327     quality = seq->strip->proxy->quality;
01328     ibuf->ftype= JPG | quality;
01329 
01330     /* unsupported feature only confuses other s/w */
01331     if(ibuf->planes==32)
01332         ibuf->planes= 24;
01333 
01334     BLI_make_existing_file(name);
01335     
01336     ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
01337     if (ok == 0) {
01338         perror(name);
01339     }
01340 
01341     IMB_freeImBuf(ibuf);
01342 }
01343 
01344 void seq_proxy_rebuild(struct Main * bmain, Scene *scene, Sequence * seq,
01345                short *stop, short *do_update, float *progress)
01346 {
01347     SeqRenderData context;
01348     int cfra;
01349     int tc_flags;
01350     int size_flags;
01351     int quality;
01352 
01353     if (!seq->strip || !seq->strip->proxy) {
01354         return;
01355     }
01356 
01357     if (!(seq->flag & SEQ_USE_PROXY)) {
01358         return;
01359     }
01360 
01361     tc_flags   = seq->strip->proxy->build_tc_flags;
01362     size_flags = seq->strip->proxy->build_size_flags;
01363     quality    = seq->strip->proxy->quality;
01364 
01365     if (seq->type == SEQ_MOVIE) {
01366         seq_open_anim_file(seq);
01367 
01368         if (seq->anim) {
01369             IMB_anim_index_rebuild(
01370                 seq->anim, tc_flags, size_flags, quality,
01371                 stop, do_update, progress);
01372         }
01373         return;
01374     }
01375 
01376     if (!(seq->flag & SEQ_USE_PROXY)) {
01377         return;
01378     }
01379 
01380     /* that's why it is called custom... */
01381     if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
01382         return;
01383     }
01384 
01385     /* fail safe code */
01386 
01387     context = seq_new_render_data(
01388         bmain, scene, 
01389         (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f, 
01390         (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 
01391         100);
01392 
01393     for (cfra = seq->startdisp + seq->startstill; 
01394          cfra < seq->enddisp - seq->endstill; cfra++) {
01395         if (size_flags & IMB_PROXY_25) {
01396             seq_proxy_build_frame(context, seq, cfra, 25);
01397         }
01398         if (size_flags & IMB_PROXY_50) {
01399             seq_proxy_build_frame(context, seq, cfra, 50);
01400         }
01401         if (size_flags & IMB_PROXY_75) {
01402             seq_proxy_build_frame(context, seq, cfra, 75);
01403         }
01404         if (size_flags & IMB_PROXY_100) {
01405             seq_proxy_build_frame(context, seq, cfra, 100);
01406         }
01407 
01408         *progress= (float)cfra/(seq->enddisp - seq->endstill 
01409                     - seq->startdisp + seq->startstill);
01410         *do_update= 1;
01411 
01412         if(*stop || G.afbreek)
01413             break;
01414     }
01415 }
01416 
01417 
01418 /* **********************************************************************
01419    color balance 
01420    ********************************************************************** */
01421 
01422 static StripColorBalance calc_cb(StripColorBalance * cb_)
01423 {
01424     StripColorBalance cb = *cb_;
01425     int c;
01426 
01427     for (c = 0; c < 3; c++) {
01428         cb.lift[c] = 2.0f - cb.lift[c];
01429     }
01430 
01431     if(cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
01432         for (c = 0; c < 3; c++) {
01433             /* tweak to give more subtle results
01434              * values above 1.0 are scaled */
01435             if(cb.lift[c] > 1.0f)
01436                 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0;
01437 
01438             cb.lift[c] = 2.0f - cb.lift[c];
01439         }
01440     }
01441 
01442     if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
01443         for (c = 0; c < 3; c++) {
01444             if (cb.gain[c] != 0.0f) {
01445                 cb.gain[c] = 1.0f / cb.gain[c];
01446             } else {
01447                 cb.gain[c] = 1000000; /* should be enough :) */
01448             }
01449         }
01450     }
01451 
01452     if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
01453         for (c = 0; c < 3; c++) {
01454             if (cb.gamma[c] != 0.0f) {
01455                 cb.gamma[c] = 1.0f/cb.gamma[c];
01456             } else {
01457                 cb.gamma[c] = 1000000; /* should be enough :) */
01458             }
01459         }
01460     }
01461 
01462     return cb;
01463 }
01464 
01465 /* note: lift is actually 2-lift */
01466 MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
01467 {
01468     float x= (((in - 1.0f) * lift) + 1.0f) * gain;
01469 
01470     /* prevent NaN */
01471     if (x < 0.f) x = 0.f;
01472 
01473     return powf(x, gamma) * mul;
01474 }
01475 
01476 static void make_cb_table_byte(float lift, float gain, float gamma,
01477                    unsigned char * table, float mul)
01478 {
01479     int y;
01480 
01481     for (y = 0; y < 256; y++) {
01482         float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
01483         CLAMP(v, 0.0f, 1.0f);
01484         table[y] = v * 255;
01485     }
01486 }
01487 
01488 static void make_cb_table_float(float lift, float gain, float gamma,
01489                 float * table, float mul)
01490 {
01491     int y;
01492 
01493     for (y = 0; y < 256; y++) {
01494         float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
01495         table[y] = v;
01496     }
01497 }
01498 
01499 static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul)
01500 {
01501     unsigned char cb_tab[3][256];
01502     int c;
01503     unsigned char * p = (unsigned char*) ibuf->rect;
01504     unsigned char * e = p + ibuf->x * 4 * ibuf->y;
01505 
01506     StripColorBalance cb = calc_cb(seq->strip->color_balance);
01507 
01508     for (c = 0; c < 3; c++) {
01509         make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
01510                            cb_tab[c], mul);
01511     }
01512 
01513     while (p < e) {
01514         p[0] = cb_tab[0][p[0]];
01515         p[1] = cb_tab[1][p[1]];
01516         p[2] = cb_tab[2][p[2]];
01517         
01518         p += 4;
01519     }
01520 }
01521 
01522 static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul)
01523 {
01524     float cb_tab[4][256];
01525     int c,i;
01526     unsigned char * p = (unsigned char*) ibuf->rect;
01527     unsigned char * e = p + ibuf->x * 4 * ibuf->y;
01528     float * o;
01529     StripColorBalance cb;
01530 
01531     imb_addrectfloatImBuf(ibuf);
01532 
01533     o = ibuf->rect_float;
01534 
01535     cb = calc_cb(seq->strip->color_balance);
01536 
01537     for (c = 0; c < 3; c++) {
01538         make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
01539     }
01540 
01541     for (i = 0; i < 256; i++) {
01542         cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
01543     }
01544 
01545     while (p < e) {
01546         o[0] = cb_tab[0][p[0]];
01547         o[1] = cb_tab[1][p[1]];
01548         o[2] = cb_tab[2][p[2]];
01549         o[3] = cb_tab[3][p[3]];
01550 
01551         p += 4; o += 4;
01552     }
01553 }
01554 
01555 static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul)
01556 {
01557     float * p = ibuf->rect_float;
01558     float * e = ibuf->rect_float + ibuf->x * 4* ibuf->y;
01559     StripColorBalance cb = calc_cb(seq->strip->color_balance);
01560 
01561     while (p < e) {
01562         int c;
01563         for (c = 0; c < 3; c++) {
01564             p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
01565         }
01566         p += 4;
01567     }
01568 }
01569 
01570 static void color_balance(Sequence * seq, ImBuf* ibuf, float mul)
01571 {
01572     if (ibuf->rect_float) {
01573         color_balance_float_float(seq, ibuf, mul);
01574     } else if(seq->flag & SEQ_MAKE_FLOAT) {
01575         color_balance_byte_float(seq, ibuf, mul);
01576     } else {
01577         color_balance_byte_byte(seq, ibuf, mul);
01578     }
01579 }
01580 
01581 /*
01582   input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
01583 
01584   Do all the things you can't really do afterwards using sequence effects
01585   (read: before rescaling to render resolution has been done)
01586 
01587   Order is important!
01588 
01589   - Deinterlace
01590   - Crop and transform in image source coordinate space
01591   - Flip X + Flip Y (could be done afterwards, backward compatibility)
01592   - Promote image to float data (affects pipeline operations afterwards)
01593   - Color balance (is most efficient in the byte -> float 
01594     (future: half -> float should also work fine!)
01595     case, if done on load, since we can use lookup tables)
01596   - Premultiply
01597 
01598 */
01599 
01600 int input_have_to_preprocess(
01601     SeqRenderData UNUSED(context), Sequence * seq, float UNUSED(cfra))
01602 {
01603     float mul;
01604 
01605     if (seq->flag & (SEQ_FILTERY|SEQ_USE_CROP|SEQ_USE_TRANSFORM|SEQ_FLIPX|
01606              SEQ_FLIPY|SEQ_USE_COLOR_BALANCE|SEQ_MAKE_PREMUL)) {
01607         return TRUE;
01608     }
01609 
01610     mul = seq->mul;
01611 
01612     if(seq->blend_mode == SEQ_BLEND_REPLACE) {
01613         mul *= seq->blend_opacity / 100.0f;
01614     }
01615 
01616     if (mul != 1.0f) {
01617         return TRUE;
01618     }
01619 
01620     if (seq->sat != 1.0f) {
01621         return TRUE;
01622     }
01623         
01624     return FALSE;
01625 }
01626 
01627 static ImBuf * input_preprocess(
01628     SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf * ibuf)
01629 {
01630     float mul;
01631 
01632     ibuf = IMB_makeSingleUser(ibuf);
01633 
01634     if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) {
01635         IMB_filtery(ibuf);
01636     }
01637 
01638     if(seq->flag & (SEQ_USE_CROP|SEQ_USE_TRANSFORM)) {
01639         StripCrop c= {0};
01640         StripTransform t= {0};
01641         int sx,sy,dx,dy;
01642 
01643         if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
01644             c = *seq->strip->crop;
01645         }
01646         if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
01647             t = *seq->strip->transform;
01648         }
01649 
01650         sx = ibuf->x - c.left - c.right;
01651         sy = ibuf->y - c.top - c.bottom;
01652         dx = sx;
01653         dy = sy;
01654 
01655         if (seq->flag & SEQ_USE_TRANSFORM) {
01656             dx = context.scene->r.xsch;
01657             dy = context.scene->r.ysch;
01658         }
01659 
01660         if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x ||
01661                 t.xofs >= dx || t.yofs >= dy) {
01662             make_black_ibuf(ibuf);
01663         } else {
01664             ImBuf * i = IMB_allocImBuf(dx, dy,32, ibuf->rect_float ? IB_rectfloat : IB_rect);
01665 
01666             IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
01667             
01668             IMB_freeImBuf(ibuf);
01669 
01670             ibuf = i;
01671         }
01672     } 
01673 
01674     if(seq->flag & SEQ_FLIPX) {
01675         IMB_flipx(ibuf);
01676     }
01677     
01678     if(seq->flag & SEQ_FLIPY) {
01679         IMB_flipy(ibuf);
01680     }
01681 
01682     if(seq->sat != 1.0f) {
01683         /* inline for now, could become an imbuf function */
01684         int i;
01685         unsigned char *rct= (unsigned char *)ibuf->rect;
01686         float *rctf= ibuf->rect_float;
01687         const float sat= seq->sat;
01688         float hsv[3];
01689 
01690         if(rct) {
01691             float rgb[3];
01692             for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
01693                 rgb_byte_to_float(rct, rgb);
01694                 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
01695                 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
01696                 rgb_float_to_byte(rgb, rct);
01697             }
01698         }
01699 
01700         if(rctf) {
01701             for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
01702                 rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
01703                 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
01704             }
01705         }
01706     }
01707 
01708     mul = seq->mul;
01709 
01710     if(seq->blend_mode == SEQ_BLEND_REPLACE) {
01711         mul *= seq->blend_opacity / 100.0f;
01712     }
01713 
01714     if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
01715         color_balance(seq, ibuf, mul);
01716         mul = 1.0;
01717     }
01718 
01719     if(seq->flag & SEQ_MAKE_FLOAT) {
01720         if (!ibuf->rect_float)
01721             IMB_float_from_rect_simple(ibuf);
01722 
01723         if (ibuf->rect) {
01724             imb_freerectImBuf(ibuf);
01725         }
01726     }
01727 
01728     if(mul != 1.0f) {
01729         multibuf(ibuf, mul);
01730     }
01731 
01732     if(seq->flag & SEQ_MAKE_PREMUL) {
01733         if(ibuf->planes == 32 && ibuf->zbuf == NULL) {
01734             IMB_premultiply_alpha(ibuf);
01735         }
01736     }
01737 
01738 
01739     if(ibuf->x != context.rectx || ibuf->y != context.recty ) {
01740         if(context.scene->r.mode & R_OSA) {
01741             IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
01742         } else {
01743             IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty);
01744         }
01745     }
01746     return ibuf;
01747 }
01748 
01749 static ImBuf * copy_from_ibuf_still(SeqRenderData context, Sequence * seq, 
01750                     float nr)
01751 {
01752     ImBuf * rval = NULL;
01753     ImBuf * ibuf = NULL;
01754 
01755     if (nr == 0) {
01756         ibuf = seq_stripelem_cache_get(
01757             context, seq, seq->start, 
01758             SEQ_STRIPELEM_IBUF_STARTSTILL);
01759     } else if (nr == seq->len - 1) {
01760         ibuf = seq_stripelem_cache_get(
01761             context, seq, seq->start, 
01762             SEQ_STRIPELEM_IBUF_ENDSTILL);
01763     }
01764 
01765     if (ibuf) {
01766         rval = IMB_dupImBuf(ibuf);
01767         IMB_freeImBuf(ibuf);
01768     }
01769 
01770     return rval;
01771 }
01772 
01773 static void copy_to_ibuf_still(SeqRenderData context, Sequence * seq, float nr,
01774                    ImBuf * ibuf)
01775 {
01776     if (nr == 0 || nr == seq->len - 1) {
01777         /* we have to store a copy, since the passed ibuf
01778            could be preprocessed afterwards (thereby silently
01779            changing the cached image... */
01780         ibuf = IMB_dupImBuf(ibuf);
01781 
01782         if (nr == 0) {
01783             seq_stripelem_cache_put(
01784                 context, seq, seq->start, 
01785                 SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
01786         } 
01787 
01788         if (nr == seq->len - 1) {
01789             seq_stripelem_cache_put(
01790                 context, seq, seq->start, 
01791                 SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
01792         }
01793 
01794         IMB_freeImBuf(ibuf);
01795     }
01796 }
01797 
01798 /* **********************************************************************
01799    strip rendering functions
01800    ********************************************************************** */
01801 
01802 static ImBuf* seq_render_strip_stack( 
01803     SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
01804 
01805 static ImBuf * seq_render_strip(
01806     SeqRenderData context, Sequence * seq, float cfra);
01807 
01808 
01809 static ImBuf* seq_render_effect_strip_impl(
01810     SeqRenderData context, Sequence *seq, float cfra)
01811 {
01812     float fac, facf;
01813     int early_out;
01814     int i;
01815     struct SeqEffectHandle sh = get_sequence_effect(seq);
01816     FCurve *fcu= NULL;
01817     ImBuf * ibuf[3];
01818     Sequence *input[3];
01819     ImBuf * out = NULL;
01820 
01821     ibuf[0] = ibuf[1] = ibuf[2] = NULL;
01822 
01823     input[0] = seq->seq1; input[1] = seq->seq2; input[2] = seq->seq3;
01824 
01825     if (!sh.execute) { /* effect not supported in this version... */
01826         out = IMB_allocImBuf((short)context.rectx, 
01827                      (short)context.recty, 32, IB_rect);
01828         return out;
01829     }
01830 
01831     if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
01832         sh.get_default_fac(seq, cfra, &fac, &facf);
01833         
01834         if ((context.scene->r.mode & R_FIELDS)==0)
01835             facf= fac;
01836     }
01837     else {
01838         fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
01839         if (fcu) {
01840             fac = facf = evaluate_fcurve(fcu, cfra);
01841             if( context.scene->r.mode & R_FIELDS ) {
01842                 facf = evaluate_fcurve(fcu, cfra + 0.5f);
01843             }
01844         } else {
01845             fac = facf = seq->effect_fader;
01846         }
01847     }
01848 
01849     early_out = sh.early_out(seq, fac, facf);
01850 
01851     switch (early_out) {
01852     case EARLY_NO_INPUT:
01853         out = sh.execute(context, seq, cfra, fac, facf,
01854                          NULL, NULL, NULL);
01855         break;
01856     case EARLY_DO_EFFECT:
01857         for(i=0; i<3; i++) {
01858             if(input[i])
01859                 ibuf[i] = seq_render_strip(
01860                             context, input[i], cfra);
01861         }
01862 
01863         if (ibuf[0] && ibuf[1]) {
01864             out = sh.execute(context, seq, cfra, fac, facf,  
01865                      ibuf[0], ibuf[1], ibuf[2]);
01866         }
01867         break;
01868     case EARLY_USE_INPUT_1:
01869         if (input[0]) {
01870             ibuf[0] = seq_render_strip(context, input[0], cfra);
01871         }
01872         if (ibuf[0]) {
01873             if (input_have_to_preprocess(context, seq, cfra)) {
01874                 out = IMB_dupImBuf(ibuf[0]);
01875             } else {
01876                 out = ibuf[0];
01877                 IMB_refImBuf(out);
01878             }
01879         }
01880         break;
01881     case EARLY_USE_INPUT_2:
01882         if (input[1]) {
01883             ibuf[1] = seq_render_strip(context, input[1], cfra);
01884         }
01885         if (ibuf[1]) {
01886             if (input_have_to_preprocess(context, seq, cfra)) {
01887                 out = IMB_dupImBuf(ibuf[1]);
01888             } else {
01889                 out = ibuf[1];
01890                 IMB_refImBuf(out);
01891             }
01892         }
01893         break;
01894     }
01895 
01896     for (i = 0; i < 3; i++) {
01897         IMB_freeImBuf(ibuf[i]);
01898     }
01899 
01900     if (out == NULL) {
01901         out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
01902     }
01903 
01904     return out;
01905 }
01906 
01907 
01908 static ImBuf * seq_render_scene_strip_impl(
01909     SeqRenderData context, Sequence * seq, float nr)
01910 {
01911     ImBuf * ibuf = NULL;
01912     float frame= seq->sfra + nr + seq->anim_startofs;
01913     float oldcfra;
01914     Object *camera;
01915     ListBase oldmarkers;
01916     
01917     /* Old info:
01918        Hack! This function can be called from do_render_seq(), in that case
01919        the seq->scene can already have a Render initialized with same name,
01920        so we have to use a default name. (compositor uses scene name to
01921        find render).
01922        However, when called from within the UI (image preview in sequencer)
01923        we do want to use scene Render, that way the render result is defined
01924        for display in render/imagewindow
01925        
01926        Hmm, don't see, why we can't do that all the time,
01927        and since G.rendering is uhm, gone... (Peter)
01928     */
01929 
01930     /* New info:
01931        Using the same name for the renders works just fine as the do_render_seq()
01932        render is not used while the scene strips are rendered.
01933        
01934        However rendering from UI (through sequencer_preview_area_draw) can crash in
01935        very many cases since other renders (material preview, an actual render etc.)
01936        can be started while this sequence preview render is running. The only proper
01937        solution is to make the sequencer preview render a proper job, which can be
01938        stopped when needed. This would also give a nice progress bar for the preview
01939        space so that users know there's something happening.
01940 
01941        As a result the active scene now only uses OpenGL rendering for the sequencer
01942        preview. This is far from nice, but is the only way to prevent crashes at this
01943        time. 
01944 
01945        -jahka
01946     */
01947 
01948     int rendering = G.rendering;
01949     int doseq;
01950     int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1;
01951     int have_seq= FALSE;
01952     Scene *scene;
01953 
01954     /* dont refer to seq->scene above this point!, it can be NULL */
01955     if(seq->scene == NULL) {
01956         return NULL;
01957     }
01958 
01959     scene= seq->scene;
01960 
01961     have_seq= (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
01962 
01963     oldcfra= scene->r.cfra; 
01964     scene->r.cfra= frame;
01965 
01966     if(seq->scene_camera)   
01967         camera= seq->scene_camera;
01968     else {  
01969         scene_camera_switch_update(scene);
01970         camera= scene->camera;
01971     }
01972 
01973     if(have_seq==FALSE && camera==NULL) {
01974         scene->r.cfra= oldcfra;
01975         return NULL;
01976     }
01977 
01978     /* prevent eternal loop */
01979     doseq= context.scene->r.scemode & R_DOSEQ;
01980     context.scene->r.scemode &= ~R_DOSEQ;
01981     
01982 #ifdef DURIAN_CAMERA_SWITCH
01983     /* stooping to new low's in hackyness :( */
01984     oldmarkers= scene->markers;
01985     scene->markers.first= scene->markers.last= NULL;
01986 #else
01987     (void)oldmarkers;
01988 #endif
01989     
01990     if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && camera) {
01991         char err_out[256]= "unknown";
01992         /* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */
01993         if(context.scene->r.seq_prev_type==0)
01994             context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */; 
01995 
01996         /* opengl offscreen render */
01997         scene_update_for_newframe(context.bmain, scene, scene->lay);
01998         ibuf= sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out);
01999         if(ibuf == NULL) {
02000             fprintf(stderr, "seq_render_scene_strip_impl failed to get opengl buffer: %s\n", err_out);
02001         }
02002     }
02003     else {
02004         Render *re = RE_GetRender(scene->id.name);
02005         RenderResult rres;
02006 
02007         /* XXX: this if can be removed when sequence preview rendering uses the job system */
02008         if(rendering || context.scene != scene) {
02009             if(re==NULL)
02010                 re= RE_NewRender(scene->id.name);
02011             
02012             RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
02013 
02014             /* restore previous state after it was toggled on & off by RE_BlenderFrame */
02015             G.rendering = rendering;
02016         }
02017         
02018         RE_AcquireResultImage(re, &rres);
02019         
02020         if(rres.rectf) {
02021             ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat);
02022             memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
02023             if(rres.rectz) {
02024                 addzbuffloatImBuf(ibuf);
02025                 memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
02026             }
02027 
02028             /* float buffers in the sequencer are not linear */
02029             if(scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
02030                 ibuf->profile= IB_PROFILE_LINEAR_RGB;
02031             else
02032                 ibuf->profile= IB_PROFILE_NONE;
02033             IMB_convert_profile(ibuf, IB_PROFILE_SRGB);         
02034         }
02035         else if (rres.rect32) {
02036             ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
02037             memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
02038         }
02039         
02040         RE_ReleaseResultImage(re);
02041         
02042         // BIF_end_render_callbacks();
02043     }
02044     
02045     /* restore */
02046     context.scene->r.scemode |= doseq;
02047     
02048     scene->r.cfra = oldcfra;
02049 
02050     if(frame != oldcfra)
02051         scene_update_for_newframe(context.bmain, scene, scene->lay);
02052     
02053 #ifdef DURIAN_CAMERA_SWITCH
02054     /* stooping to new low's in hackyness :( */
02055     scene->markers= oldmarkers;
02056 #endif
02057 
02058     return ibuf;
02059 }
02060 
02061 static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfra)
02062 {
02063     ImBuf * ibuf = NULL;
02064     char name[FILE_MAX];
02065     int use_preprocess = input_have_to_preprocess(context, seq, cfra);
02066     float nr = give_stripelem_index(seq, cfra);
02067     /* all effects are handled similarly with the exception of speed effect */
02068     int type = (seq->type & SEQ_EFFECT && seq->type != SEQ_SPEED) ? SEQ_EFFECT : seq->type;
02069 
02070     ibuf = seq_stripelem_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
02071 
02072     /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
02073        but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
02074     if (ibuf)
02075         use_preprocess = FALSE;
02076 
02077     if (ibuf == NULL)
02078         ibuf = copy_from_ibuf_still(context, seq, nr);
02079     
02080     if (ibuf == NULL)
02081         ibuf = seq_proxy_fetch(context, seq, cfra);
02082 
02083     if(ibuf == NULL) switch(type) {
02084         case SEQ_META:
02085         {
02086             ImBuf * meta_ibuf = NULL;
02087 
02088             if(seq->seqbase.first)
02089                 meta_ibuf = seq_render_strip_stack(
02090                     context, &seq->seqbase,
02091                     seq->start + nr, 0);
02092 
02093             if(meta_ibuf) {
02094                 ibuf = meta_ibuf;
02095                 if(ibuf && use_preprocess) {
02096                     struct ImBuf * i = IMB_dupImBuf(ibuf);
02097 
02098                     IMB_freeImBuf(ibuf);
02099 
02100                     ibuf = i;
02101                 }
02102             }
02103             break;
02104         }
02105         case SEQ_SPEED:
02106         {
02107             ImBuf * child_ibuf = NULL;
02108 
02109             float f_cfra;
02110             SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
02111 
02112             sequence_effect_speed_rebuild_map(context.scene,seq, 0);
02113 
02114             /* weeek! */
02115             f_cfra = seq->start + s->frameMap[(int) nr];
02116 
02117             child_ibuf = seq_render_strip(context,seq->seq1,f_cfra);
02118 
02119             if (child_ibuf) {
02120                 ibuf = child_ibuf;
02121                 if(ibuf && use_preprocess) {
02122                     struct ImBuf * i = IMB_dupImBuf(ibuf);
02123 
02124                     IMB_freeImBuf(ibuf);
02125 
02126                     ibuf = i;
02127                 }
02128             }
02129             break;
02130         }
02131         case SEQ_EFFECT:
02132         {
02133             ibuf = seq_render_effect_strip_impl(
02134                 context, seq, seq->start + nr);
02135             break;
02136         }
02137         case SEQ_IMAGE:
02138         {
02139             StripElem * s_elem = give_stripelem(seq, cfra);
02140 
02141             if (s_elem) {
02142                 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
02143                 BLI_path_abs(name, G.main->name);
02144             }
02145 
02146             if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
02147                 /* we don't need both (speed reasons)! */
02148                 if (ibuf->rect_float && ibuf->rect)
02149                     imb_freerectImBuf(ibuf);
02150 
02151                 /* all sequencer color is done in SRGB space, linear gives odd crossfades */
02152                 if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
02153                     IMB_convert_profile(ibuf, IB_PROFILE_NONE);
02154 
02155                 copy_to_ibuf_still(context, seq, nr, ibuf);
02156 
02157                 s_elem->orig_width  = ibuf->x;
02158                 s_elem->orig_height = ibuf->y;
02159             }
02160             break;
02161         }
02162         case SEQ_MOVIE:
02163         {
02164             seq_open_anim_file(seq);
02165 
02166             if(seq->anim) {
02167                 IMB_anim_set_preseek(seq->anim,
02168                              seq->anim_preseek);
02169 
02170                 ibuf = IMB_anim_absolute(
02171                     seq->anim, nr + seq->anim_startofs, 
02172                     seq->strip->proxy ? 
02173                     seq->strip->proxy->tc
02174                     : IMB_TC_RECORD_RUN, 
02175                     seq_rendersize_to_proxysize(
02176                         context.preview_render_size));
02177 
02178                 /* we don't need both (speed reasons)! */
02179                 if (ibuf && ibuf->rect_float && ibuf->rect)
02180                     imb_freerectImBuf(ibuf);
02181                 if (ibuf) {
02182                     seq->strip->stripdata->orig_width = ibuf->x;
02183                     seq->strip->stripdata->orig_height = ibuf->y;
02184                 }
02185             }
02186             copy_to_ibuf_still(context, seq, nr, ibuf);
02187             break;
02188         }
02189         case SEQ_SCENE:
02190         {   // scene can be NULL after deletions
02191             ibuf = seq_render_scene_strip_impl(context, seq, nr);
02192 
02193             /* Scene strips update all animation, so we need to restore original state.*/
02194             BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
02195 
02196             copy_to_ibuf_still(context, seq, nr, ibuf);
02197             break;
02198         }
02199     }
02200 
02201     if (ibuf == NULL)
02202         ibuf = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
02203 
02204     if (ibuf->x != context.rectx || ibuf->y != context.recty)
02205         use_preprocess = TRUE;
02206 
02207     if (use_preprocess)
02208         ibuf = input_preprocess(context, seq, cfra, ibuf);
02209 
02210     seq_stripelem_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
02211 
02212     return ibuf;
02213 }
02214 
02215 /* **********************************************************************
02216    strip stack rendering functions
02217    ********************************************************************** */
02218 
02219 static int seq_must_swap_input_in_blend_mode(Sequence * seq)
02220 {
02221     int swap_input = FALSE;
02222 
02223     /* bad hack, to fix crazy input ordering of 
02224        those two effects */
02225 
02226     if (ELEM3(seq->blend_mode, SEQ_ALPHAOVER, SEQ_ALPHAUNDER, SEQ_OVERDROP)) {
02227         swap_input = TRUE;
02228     }
02229     
02230     return swap_input;
02231 }
02232 
02233 static int seq_get_early_out_for_blend_mode(Sequence * seq)
02234 {
02235     struct SeqEffectHandle sh = get_sequence_blend(seq);
02236     float facf = seq->blend_opacity / 100.0f;
02237     int early_out = sh.early_out(seq, facf, facf);
02238     
02239     if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) {
02240         return early_out;
02241     }
02242 
02243     if (seq_must_swap_input_in_blend_mode(seq)) {
02244         if (early_out == EARLY_USE_INPUT_2) {
02245             return EARLY_USE_INPUT_1;
02246         } else if (early_out == EARLY_USE_INPUT_1) {
02247             return EARLY_USE_INPUT_2;
02248         }
02249     }
02250     return early_out;
02251 }
02252 
02253 static ImBuf* seq_render_strip_stack(
02254     SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown)
02255 {
02256     Sequence* seq_arr[MAXSEQ+1];
02257     int count;
02258     int i;
02259     ImBuf* out = NULL;
02260 
02261     count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
02262 
02263     if (count == 0) {
02264         return NULL;
02265     }
02266 
02267 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
02268     if(scene->r.cfra != cfra) {
02269         // XXX for prefetch and overlay offset!..., very bad!!!
02270         AnimData *adt= BKE_animdata_from_id(&scene->id);
02271         BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
02272     }
02273 #endif
02274 
02275     out = seq_stripelem_cache_get(context, seq_arr[count - 1], 
02276                       cfra, SEQ_STRIPELEM_IBUF_COMP);
02277 
02278     if (out) {
02279         return out;
02280     }
02281     
02282     if(count == 1) {
02283         out = seq_render_strip(context, seq_arr[0], cfra);
02284         seq_stripelem_cache_put(context, seq_arr[0], cfra, 
02285                     SEQ_STRIPELEM_IBUF_COMP, out);
02286 
02287         return out;
02288     }
02289 
02290 
02291     for (i = count - 1; i >= 0; i--) {
02292         int early_out;
02293         Sequence *seq = seq_arr[i];
02294 
02295         out = seq_stripelem_cache_get(
02296             context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP);
02297 
02298         if (out) {
02299             break;
02300         }
02301         if (seq->blend_mode == SEQ_BLEND_REPLACE) {
02302             out = seq_render_strip(context, seq, cfra);
02303             break;
02304         }
02305 
02306         early_out = seq_get_early_out_for_blend_mode(seq);
02307 
02308         switch (early_out) {
02309         case EARLY_NO_INPUT:
02310         case EARLY_USE_INPUT_2:
02311             out = seq_render_strip(context, seq, cfra);
02312             break;
02313         case EARLY_USE_INPUT_1:
02314             if (i == 0) {
02315                 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect);
02316             }
02317             break;
02318         case EARLY_DO_EFFECT:
02319             if (i == 0) {
02320                 out = seq_render_strip(context, seq, cfra);
02321             }
02322 
02323             break;
02324         }
02325         if (out) {
02326             break;
02327         }
02328     }
02329 
02330     seq_stripelem_cache_put(context, seq_arr[i], cfra, 
02331                 SEQ_STRIPELEM_IBUF_COMP, out);
02332 
02333 
02334     i++;
02335 
02336     for (; i < count; i++) {
02337         Sequence * seq = seq_arr[i];
02338 
02339         if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) {
02340             struct SeqEffectHandle sh = get_sequence_blend(seq);
02341             ImBuf * ibuf1 = out;
02342             ImBuf * ibuf2 = seq_render_strip(context, seq, cfra);
02343 
02344             float facf = seq->blend_opacity / 100.0f;
02345             int swap_input = seq_must_swap_input_in_blend_mode(seq);
02346 
02347             if (swap_input) {
02348                 out = sh.execute(context, seq, cfra, 
02349                          facf, facf, 
02350                          ibuf2, ibuf1, NULL);
02351             } else {
02352                 out = sh.execute(context, seq, cfra, 
02353                          facf, facf, 
02354                          ibuf1, ibuf2, NULL);
02355             }
02356         
02357             IMB_freeImBuf(ibuf1);
02358             IMB_freeImBuf(ibuf2);
02359         }
02360 
02361         seq_stripelem_cache_put(context, seq_arr[i], cfra,
02362                     SEQ_STRIPELEM_IBUF_COMP, out);
02363     }
02364 
02365     return out;
02366 }
02367 
02368 /*
02369  * returned ImBuf is refed!
02370  * you have to free after usage!
02371  */
02372 
02373 ImBuf *give_ibuf_seq(SeqRenderData context, float cfra, int chanshown)
02374 {
02375     Editing *ed= seq_give_editing(context.scene, FALSE);
02376     int count;
02377     ListBase *seqbasep;
02378     
02379     if(ed==NULL) return NULL;
02380 
02381     count = BLI_countlist(&ed->metastack);
02382     if((chanshown < 0) && (count > 0)) {
02383         count = MAX2(count + chanshown, 0);
02384         seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
02385     } else {
02386         seqbasep= ed->seqbasep;
02387     }
02388 
02389     return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
02390 }
02391 
02392 ImBuf *give_ibuf_seqbase(SeqRenderData context, float cfra, int chanshown, ListBase *seqbasep)
02393 {
02394     return seq_render_strip_stack(context, seqbasep, cfra, chanshown);
02395 }
02396 
02397 
02398 ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, Sequence *seq)
02399 {
02400     return seq_render_strip(context, seq, cfra);
02401 }
02402 
02403 #if 0
02404 /* check used when we need to change seq->blend_mode but not to effect or audio strips */
02405 static int seq_can_blend(Sequence *seq)
02406 {
02407     if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
02408         return 1;
02409     } else {
02410         return 0;
02411     }
02412 }
02413 #endif
02414 
02415 /* *********************** threading api ******************* */
02416 
02417 static ListBase running_threads;
02418 static ListBase prefetch_wait;
02419 static ListBase prefetch_done;
02420 
02421 static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
02422 static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
02423 static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
02424 
02425 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
02426 //static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
02427 
02428 static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
02429 static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
02430 
02431 static volatile int seq_thread_shutdown = TRUE; 
02432 static volatile int seq_last_given_monoton_cfra = 0;
02433 static int monoton_cfra = 0;
02434 
02435 typedef struct PrefetchThread {
02436     struct PrefetchThread *next, *prev;
02437     
02438     Scene *scene;
02439     struct PrefetchQueueElem *current;
02440     pthread_t pthread;
02441     int running;
02442     
02443 } PrefetchThread;
02444 
02445 typedef struct PrefetchQueueElem {
02446     struct PrefetchQueueElem *next, *prev;
02447     
02448     int rectx;
02449     int recty;
02450     float cfra;
02451     int chanshown;
02452     int preview_render_size;
02453 
02454     int monoton_cfra;
02455 
02456     struct ImBuf * ibuf;
02457 } PrefetchQueueElem;
02458 
02459 #if 0
02460 static void *seq_prefetch_thread(void * This_)
02461 {
02462     PrefetchThread * This = This_;
02463 
02464     while (!seq_thread_shutdown) {
02465         PrefetchQueueElem *e;
02466         int s_last;
02467 
02468         pthread_mutex_lock(&queue_lock);
02469         e = prefetch_wait.first;
02470         if (e) {
02471             BLI_remlink(&prefetch_wait, e);
02472         }
02473         s_last = seq_last_given_monoton_cfra;
02474 
02475         This->current = e;
02476 
02477         pthread_mutex_unlock(&queue_lock);
02478 
02479         if (!e) {
02480             pthread_mutex_lock(&prefetch_ready_lock);
02481 
02482             This->running = FALSE;
02483 
02484             pthread_cond_signal(&prefetch_ready_cond);
02485             pthread_mutex_unlock(&prefetch_ready_lock);
02486 
02487             pthread_mutex_lock(&wakeup_lock);
02488             if (!seq_thread_shutdown) {
02489                 pthread_cond_wait(&wakeup_cond, &wakeup_lock);
02490             }
02491             pthread_mutex_unlock(&wakeup_lock);
02492             continue;
02493         }
02494 
02495         This->running = TRUE;
02496         
02497         if (e->cfra >= s_last) { 
02498             e->ibuf = give_ibuf_seq_impl(This->scene, 
02499                 e->rectx, e->recty, e->cfra, e->chanshown,
02500                 e->preview_render_size);
02501         }
02502 
02503         pthread_mutex_lock(&queue_lock);
02504 
02505         BLI_addtail(&prefetch_done, e);
02506 
02507         for (e = prefetch_wait.first; e; e = e->next) {
02508             if (s_last > e->monoton_cfra) {
02509                 BLI_remlink(&prefetch_wait, e);
02510                 MEM_freeN(e);
02511             }
02512         }
02513 
02514         for (e = prefetch_done.first; e; e = e->next) {
02515             if (s_last > e->monoton_cfra) {
02516                 BLI_remlink(&prefetch_done, e);
02517                 MEM_freeN(e);
02518             }
02519         }
02520 
02521         pthread_mutex_unlock(&queue_lock);
02522 
02523         pthread_mutex_lock(&frame_done_lock);
02524         pthread_cond_signal(&frame_done_cond);
02525         pthread_mutex_unlock(&frame_done_lock);
02526     }
02527     return 0;
02528 }
02529 
02530 static void seq_start_threads(Scene *scene)
02531 {
02532     int i;
02533 
02534     running_threads.first = running_threads.last = NULL;
02535     prefetch_wait.first = prefetch_wait.last = NULL;
02536     prefetch_done.first = prefetch_done.last = NULL;
02537 
02538     seq_thread_shutdown = FALSE;
02539     seq_last_given_monoton_cfra = monoton_cfra = 0;
02540 
02541     /* since global structures are modified during the processing
02542        of one frame, only one render thread is currently possible... 
02543 
02544        (but we code, in the hope, that we can remove this restriction
02545        soon...)
02546     */
02547 
02548     fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
02549 
02550     for (i = 0; i < 1; i++) {
02551         PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread");
02552         t->scene= scene;
02553         t->running = TRUE;
02554         BLI_addtail(&running_threads, t);
02555 
02556         pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
02557     }
02558 
02559     /* init malloc mutex */
02560     BLI_init_threads(0, 0, 0);
02561 }
02562 
02563 static void seq_stop_threads()
02564 {
02565     PrefetchThread *tslot;
02566     PrefetchQueueElem *e;
02567 
02568     fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
02569 
02570     if (seq_thread_shutdown) {
02571         fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
02572         return;
02573     }
02574     
02575     pthread_mutex_lock(&wakeup_lock);
02576 
02577     seq_thread_shutdown = TRUE;
02578 
02579         pthread_cond_broadcast(&wakeup_cond);
02580         pthread_mutex_unlock(&wakeup_lock);
02581 
02582     for(tslot = running_threads.first; tslot; tslot= tslot->next) {
02583         pthread_join(tslot->pthread, NULL);
02584     }
02585 
02586 
02587     for (e = prefetch_wait.first; e; e = e->next) {
02588         BLI_remlink(&prefetch_wait, e);
02589         MEM_freeN(e);
02590     }
02591 
02592     for (e = prefetch_done.first; e; e = e->next) {
02593         BLI_remlink(&prefetch_done, e);
02594         MEM_freeN(e);
02595     }
02596 
02597     BLI_freelistN(&running_threads);
02598 
02599     /* deinit malloc mutex */
02600     BLI_end_threads(0);
02601 }
02602 #endif
02603 
02604 void give_ibuf_prefetch_request(SeqRenderData context, float cfra, int chanshown)
02605 {
02606     PrefetchQueueElem *e;
02607     if (seq_thread_shutdown) {
02608         return;
02609     }
02610 
02611     e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
02612     e->rectx = context.rectx;
02613     e->recty = context.recty;
02614     e->cfra = cfra;
02615     e->chanshown = chanshown;
02616     e->preview_render_size = context.preview_render_size;
02617     e->monoton_cfra = monoton_cfra++;
02618 
02619     pthread_mutex_lock(&queue_lock);
02620     BLI_addtail(&prefetch_wait, e);
02621     pthread_mutex_unlock(&queue_lock);
02622     
02623     pthread_mutex_lock(&wakeup_lock);
02624     pthread_cond_signal(&wakeup_cond);
02625     pthread_mutex_unlock(&wakeup_lock);
02626 }
02627 
02628 #if 0
02629 static void seq_wait_for_prefetch_ready()
02630 {
02631     PrefetchThread *tslot;
02632 
02633     if (seq_thread_shutdown) {
02634         return;
02635     }
02636 
02637     fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
02638 
02639     pthread_mutex_lock(&prefetch_ready_lock);
02640 
02641     for(;;) {
02642         for(tslot = running_threads.first; tslot; tslot= tslot->next) {
02643             if (tslot->running) {
02644                 break;
02645             }
02646         }
02647         if (!tslot) {
02648             break;
02649         }
02650         pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
02651     }
02652 
02653     pthread_mutex_unlock(&prefetch_ready_lock);
02654 
02655     fprintf(stderr, "SEQ-THREAD: prefetch done\n");
02656 }
02657 #endif
02658 
02659 ImBuf *give_ibuf_seq_threaded(SeqRenderData context, float cfra, int chanshown)
02660 {
02661     PrefetchQueueElem *e = NULL;
02662     int found_something = FALSE;
02663 
02664     if (seq_thread_shutdown) {
02665         return give_ibuf_seq(context, cfra, chanshown);
02666     }
02667 
02668     while (!e) {
02669         int success = FALSE;
02670         pthread_mutex_lock(&queue_lock);
02671 
02672         for (e = prefetch_done.first; e; e = e->next) {
02673             if (cfra == e->cfra &&
02674                 chanshown == e->chanshown &&
02675                 context.rectx == e->rectx && 
02676                 context.recty == e->recty &&
02677                 context.preview_render_size == e->preview_render_size) {
02678                 success = TRUE;
02679                 found_something = TRUE;
02680                 break;
02681             }
02682         }
02683 
02684         if (!e) {
02685             for (e = prefetch_wait.first; e; e = e->next) {
02686                 if (cfra == e->cfra &&
02687                     chanshown == e->chanshown &&
02688                     context.rectx == e->rectx && 
02689                     context.recty == e->recty &&
02690                     context.preview_render_size == e->preview_render_size) {
02691                     found_something = TRUE;
02692                     break;
02693                 }
02694             }
02695         }
02696 
02697         if (!e) {
02698             PrefetchThread *tslot;
02699 
02700             for(tslot = running_threads.first; 
02701                 tslot; tslot= tslot->next) {
02702                 if (tslot->current &&
02703                     cfra == tslot->current->cfra &&
02704                     chanshown == tslot->current->chanshown &&
02705                     context.rectx == tslot->current->rectx && 
02706                     context.recty == tslot->current->recty &&
02707                     context.preview_render_size== tslot->current->preview_render_size){
02708                     found_something = TRUE;
02709                     break;
02710                 }
02711             }
02712         }
02713 
02714         /* e->ibuf is unrefed by render thread on next round. */
02715 
02716         if (e) {
02717             seq_last_given_monoton_cfra = e->monoton_cfra;
02718         }
02719 
02720         pthread_mutex_unlock(&queue_lock);
02721 
02722         if (!success) {
02723             e = NULL;
02724 
02725             if (!found_something) {
02726                 fprintf(stderr, 
02727                     "SEQ-THREAD: Requested frame "
02728                     "not in queue ???\n");
02729                 break;
02730             }
02731             pthread_mutex_lock(&frame_done_lock);
02732             pthread_cond_wait(&frame_done_cond, &frame_done_lock);
02733             pthread_mutex_unlock(&frame_done_lock);
02734         }
02735     }
02736     
02737     return e ? e->ibuf : NULL;
02738 }
02739 
02740 /* Functions to free imbuf and anim data on changes */
02741 
02742 static void free_anim_seq(Sequence *seq)
02743 {
02744     if(seq->anim) {
02745         IMB_free_anim(seq->anim);
02746         seq->anim = NULL;
02747     }
02748 }
02749 
02750 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage,
02751             int keep_file_handles)
02752 {
02753     Sequence *seq;
02754 
02755     if (check_mem_usage) {
02756         /* Let the cache limitor take care of this (schlaile) */
02757         /* While render let's keep all memory available for render 
02758            (ton)
02759            At least if free memory is tight...
02760            This can make a big difference in encoding speed
02761            (it is around 4 times(!) faster, if we do not waste time
02762            on freeing _all_ buffers every time on long timelines...)
02763            (schlaile)
02764         */
02765     
02766         uintptr_t mem_in_use;
02767         uintptr_t mmap_in_use;
02768         uintptr_t max;
02769     
02770         mem_in_use= MEM_get_memory_in_use();
02771         mmap_in_use= MEM_get_mapped_memory_in_use();
02772         max = MEM_CacheLimiter_get_maximum();
02773     
02774         if (max == 0 || mem_in_use + mmap_in_use <= max) {
02775             return;
02776         }
02777     }
02778 
02779     seq_stripelem_cache_cleanup();
02780     
02781     for(seq= seqbase->first; seq; seq= seq->next) {
02782         if(seq->strip) {
02783             if(seq->type==SEQ_MOVIE && !keep_file_handles)
02784                 free_anim_seq(seq);
02785             if(seq->type==SEQ_SPEED) {
02786                 sequence_effect_speed_rebuild_map(scene, seq, 1);
02787             }
02788         }
02789         if(seq->type==SEQ_META) {
02790             free_imbuf_seq(scene, &seq->seqbase, FALSE, keep_file_handles);
02791         }
02792         if(seq->type==SEQ_SCENE) {
02793             /* FIXME: recurs downwards, 
02794                but do recurs protection somehow! */
02795         }
02796     }
02797     
02798 }
02799 
02800 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
02801 {
02802     Sequence *subseq;
02803     int free_imbuf = 0;
02804     
02805     /* recurs downwards to see if this seq depends on the changed seq */
02806     
02807     if(seq == NULL)
02808         return 0;
02809     
02810     if(seq == changed_seq)
02811         free_imbuf = 1;
02812     
02813     for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
02814         if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change))
02815             free_imbuf = TRUE;
02816     
02817     if(seq->seq1)
02818         if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change))
02819             free_imbuf = TRUE;
02820     if(seq->seq2 && (seq->seq2 != seq->seq1))
02821         if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change))
02822             free_imbuf = TRUE;
02823     if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
02824         if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change))
02825             free_imbuf = TRUE;
02826     
02827     if(free_imbuf) {
02828         if(ibuf_change) {
02829             if(seq->type == SEQ_MOVIE)
02830                 free_anim_seq(seq);
02831             if(seq->type == SEQ_SPEED) {
02832                 sequence_effect_speed_rebuild_map(scene, seq, 1);
02833             }
02834         }
02835         
02836         if(len_change)
02837             calc_sequence(scene, seq);
02838     }
02839     
02840     return free_imbuf;
02841 }
02842 
02843 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change)
02844 {
02845     Editing *ed= seq_give_editing(scene, FALSE);
02846     Sequence *seq;
02847     
02848     if (ed==NULL) return;
02849     
02850     for (seq=ed->seqbase.first; seq; seq=seq->next)
02851         update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change);
02852 }
02853 
02854 /* seq funcs's for transforming internally
02855  notice the difference between start/end and left/right.
02856 
02857  left and right are the bounds at which the sequence is rendered,
02858 start and end are from the start and fixed length of the sequence.
02859 */
02860 int seq_tx_get_start(Sequence *seq)
02861 {
02862     return seq->start;
02863 }
02864 int seq_tx_get_end(Sequence *seq)
02865 {
02866     return seq->start+seq->len;
02867 }
02868 
02869 int seq_tx_get_final_left(Sequence *seq, int metaclip)
02870 {
02871     if (metaclip && seq->tmp) {
02872         /* return the range clipped by the parents range */
02873         return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) );
02874     } else {
02875         return (seq->start - seq->startstill) + seq->startofs;
02876     }
02877 
02878 }
02879 int seq_tx_get_final_right(Sequence *seq, int metaclip)
02880 {
02881     if (metaclip && seq->tmp) {
02882         /* return the range clipped by the parents range */
02883         return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) );
02884     } else {
02885         return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
02886     }
02887 }
02888 
02889 void seq_tx_set_final_left(Sequence *seq, int val)
02890 {
02891     if (val < (seq)->start) {
02892         seq->startstill = abs(val - (seq)->start);
02893         seq->startofs = 0;
02894     } else {
02895         seq->startofs = abs(val - (seq)->start);
02896         seq->startstill = 0;
02897     }
02898 }
02899 
02900 void seq_tx_set_final_right(Sequence *seq, int val)
02901 {
02902     if (val > (seq)->start + (seq)->len) {
02903         seq->endstill = abs(val - (seq->start + (seq)->len));
02904         seq->endofs = 0;
02905     } else {
02906         seq->endofs = abs(val - ((seq)->start + (seq)->len));
02907         seq->endstill = 0;
02908     }
02909 }
02910 
02911 /* used so we can do a quick check for single image seq
02912    since they work a bit differently to normal image seq's (during transform) */
02913 int seq_single_check(Sequence *seq)
02914 {
02915     return (seq->len==1 && (
02916             seq->type == SEQ_IMAGE 
02917             || ((seq->type & SEQ_EFFECT) && 
02918                 get_sequence_effect_num_inputs(seq->type) == 0)));
02919 }
02920 
02921 /* check if the selected seq's reference unselected seq's */
02922 int seqbase_isolated_sel_check(ListBase *seqbase)
02923 {
02924     Sequence *seq;
02925     /* is there more than 1 select */
02926     int ok= FALSE;
02927 
02928     for(seq= seqbase->first; seq; seq= seq->next) {
02929         if(seq->flag & SELECT) {
02930             ok= TRUE;
02931             break;
02932         }
02933     }
02934 
02935     if(ok == FALSE)
02936         return FALSE;
02937 
02938     /* test relationships */
02939     for(seq= seqbase->first; seq; seq= seq->next) {
02940         if((seq->type & SEQ_EFFECT)==0)
02941             continue;
02942 
02943         if(seq->flag & SELECT) {
02944             if( (seq->seq1 && (seq->seq1->flag & SELECT)==0) ||
02945                 (seq->seq2 && (seq->seq2->flag & SELECT)==0) ||
02946                 (seq->seq3 && (seq->seq3->flag & SELECT)==0) )
02947                 return FALSE;
02948         }
02949         else {
02950             if( (seq->seq1 && (seq->seq1->flag & SELECT)) ||
02951                 (seq->seq2 && (seq->seq2->flag & SELECT)) ||
02952                 (seq->seq3 && (seq->seq3->flag & SELECT)) )
02953                 return FALSE;
02954         }
02955     }
02956 
02957     return TRUE;
02958 }
02959 
02960 /* use to impose limits when dragging/extending - so impossible situations dont happen
02961  * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */
02962 void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag)
02963 {
02964     if(leftflag) {
02965         if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
02966             seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1);
02967         }
02968 
02969         if (seq_single_check(seq)==0) {
02970             if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
02971                 seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
02972             }
02973 
02974             /* dosnt work now - TODO */
02975             /*
02976             if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
02977                 int ofs;
02978                 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
02979                 seq->start -= ofs;
02980                 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs );
02981             }*/
02982 
02983         }
02984     }
02985 
02986     if(rightflag) {
02987         if (seq_tx_get_final_right(seq, 0) <=  seq_tx_get_final_left(seq, 0)) {
02988             seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1);
02989         }
02990 
02991         if (seq_single_check(seq)==0) {
02992             if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
02993                 seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
02994             }
02995         }
02996     }
02997 
02998     /* sounds cannot be extended past their endpoints */
02999     if (seq->type == SEQ_SOUND) {
03000         seq->startstill= 0;
03001         seq->endstill= 0;
03002     }
03003 }
03004 
03005 void seq_single_fix(Sequence *seq)
03006 {
03007     int left, start, offset;
03008     if (!seq_single_check(seq))
03009         return;
03010 
03011     /* make sure the image is always at the start since there is only one,
03012        adjusting its start should be ok */
03013     left = seq_tx_get_final_left(seq, 0);
03014     start = seq->start;
03015     if (start != left) {
03016         offset = left - start;
03017         seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset );
03018         seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset );
03019         seq->start += offset;
03020     }
03021 }
03022 
03023 int seq_tx_test(Sequence * seq)
03024 {
03025     return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0);
03026 }
03027 
03028 static int seq_overlap(Sequence *seq1, Sequence *seq2)
03029 {
03030     return (seq1 != seq2 && seq1->machine == seq2->machine &&
03031             ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0);
03032 }
03033 
03034 int seq_test_overlap(ListBase * seqbasep, Sequence *test)
03035 {
03036     Sequence *seq;
03037 
03038     seq= seqbasep->first;
03039     while(seq) {
03040         if(seq_overlap(test, seq))
03041             return 1;
03042 
03043         seq= seq->next;
03044     }
03045     return 0;
03046 }
03047 
03048 
03049 void seq_translate(Scene *evil_scene, Sequence *seq, int delta)
03050 {
03051     seq_offset_animdata(evil_scene, seq, delta);
03052     seq->start += delta;
03053 
03054     if(seq->type==SEQ_META) {
03055         Sequence *seq_child;
03056         for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
03057             seq_translate(evil_scene, seq_child, delta);
03058         }
03059     }
03060 
03061     calc_sequence_disp(evil_scene, seq);
03062 }
03063 
03064 void seq_sound_init(Scene *scene, Sequence *seq)
03065 {
03066     if(seq->type==SEQ_META) {
03067         Sequence *seq_child;
03068         for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) {
03069             seq_sound_init(scene, seq_child);
03070         }
03071     }
03072     else {
03073         if(seq->sound) {
03074             seq->scene_sound = sound_add_scene_sound_defaults(scene, seq);
03075         }
03076         if(seq->scene) {
03077             sound_scene_add_scene_sound_defaults(scene, seq);
03078         }
03079     }
03080 }
03081 
03082 Sequence *seq_foreground_frame_get(Scene *scene, int frame)
03083 {
03084     Editing *ed= seq_give_editing(scene, FALSE);
03085     Sequence *seq, *best_seq=NULL;
03086     int best_machine = -1;
03087     
03088     if(!ed) return NULL;
03089     
03090     for (seq=ed->seqbasep->first; seq; seq= seq->next) {
03091         if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame)
03092             continue;
03093         /* only use elements you can see - not */
03094         if (ELEM5(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_COLOR)) {
03095             if (seq->machine > best_machine) {
03096                 best_seq = seq;
03097                 best_machine = seq->machine;
03098             }
03099         }
03100     }
03101     return best_seq;
03102 }
03103 
03104 /* return 0 if there werent enough space */
03105 int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene)
03106 {
03107     int orig_machine= test->machine;
03108     test->machine++;
03109     calc_sequence(evil_scene, test);
03110     while( seq_test_overlap(seqbasep, test) ) {
03111         if(test->machine >= MAXSEQ) {
03112             break;
03113         }
03114         test->machine++;
03115         calc_sequence(evil_scene, test); // XXX - I dont think this is needed since were only moving vertically, Campbell.
03116     }
03117 
03118     
03119     if(test->machine >= MAXSEQ) {
03120         /* Blender 2.4x would remove the strip.
03121          * nicer to move it to the end */
03122 
03123         Sequence *seq;
03124         int new_frame= test->enddisp;
03125 
03126         for(seq= seqbasep->first; seq; seq= seq->next) {
03127             if (seq->machine == orig_machine)
03128                 new_frame = MAX2(new_frame, seq->enddisp);
03129         }
03130 
03131         test->machine= orig_machine;
03132         new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */
03133         seq_translate(evil_scene, test, new_frame - test->start);
03134 
03135         calc_sequence(evil_scene, test);
03136         return 0;
03137     } else {
03138         return 1;
03139     }
03140 }
03141 
03142 static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir)
03143 {
03144     int offset= 0;
03145     Sequence *seq, *seq_other;
03146 
03147     for(seq= seqbasep->first; seq; seq= seq->next) {
03148         if(seq->tmp) {
03149             for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) {
03150                 if(!seq_other->tmp && seq_overlap(seq, seq_other)) {
03151                     if(dir=='L') {
03152                         offset= MIN2(offset, seq_other->startdisp - seq->enddisp);
03153                     }
03154                     else {
03155                         offset= MAX2(offset, seq_other->enddisp - seq->startdisp);
03156                     }
03157                 }
03158             }
03159         }
03160     }
03161     return offset;
03162 }
03163 
03164 static int shuffle_seq_time_offset(Scene* scene, ListBase * seqbasep, char dir)
03165 {
03166     int ofs= 0;
03167     int tot_ofs= 0;
03168     Sequence *seq;
03169     while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) {
03170         for(seq= seqbasep->first; seq; seq= seq->next) {
03171             if(seq->tmp) {
03172                 /* seq_test_overlap only tests display values */
03173                 seq->startdisp +=   ofs;
03174                 seq->enddisp +=     ofs;
03175             }
03176         }
03177 
03178         tot_ofs+= ofs;
03179     }
03180 
03181     for(seq= seqbasep->first; seq; seq= seq->next) {
03182         if(seq->tmp)
03183             calc_sequence_disp(scene, seq); /* corrects dummy startdisp/enddisp values */
03184     }
03185 
03186     return tot_ofs;
03187 }
03188 
03189 int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene)
03190 {
03191     /* note: seq->tmp is used to tag strips to move */
03192 
03193     Sequence *seq;
03194 
03195     int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L');
03196     int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R');
03197     int offset = (-offset_l < offset_r) ?  offset_l:offset_r;
03198 
03199     if(offset) {
03200         for(seq= seqbasep->first; seq; seq= seq->next) {
03201             if(seq->tmp) {
03202                 seq_translate(evil_scene, seq, offset);
03203                 seq->flag &= ~SEQ_OVERLAP;
03204             }
03205         }
03206     }
03207 
03208     return offset? 0:1;
03209 }
03210 
03211 void seq_update_sound_bounds_all(Scene *scene)
03212 {
03213     Editing *ed = scene->ed;
03214 
03215     if(ed) {
03216         Sequence *seq;
03217 
03218         for(seq = ed->seqbase.first; seq; seq = seq->next) {
03219             if(seq->type == SEQ_META) {
03220                 seq_update_sound_bounds_recursive(scene, seq);
03221             }
03222             else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
03223                 seq_update_sound_bounds(scene, seq);
03224             }
03225         }
03226     }
03227 }
03228 
03229 void seq_update_sound_bounds(Scene* scene, Sequence *seq)
03230 {
03231     sound_move_scene_sound_defaults(scene, seq);
03232     /* mute is set in seq_update_muting_recursive */
03233 }
03234 
03235 static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
03236 {
03237     Sequence *seq;
03238     int seqmute;
03239 
03240     /* for sound we go over full meta tree to update muted state,
03241        since sound is played outside of evaluating the imbufs, */
03242     for(seq=seqbasep->first; seq; seq=seq->next) {
03243         seqmute= (mute || (seq->flag & SEQ_MUTE));
03244 
03245         if(seq->type == SEQ_META) {
03246             /* if this is the current meta sequence, unmute because
03247                all sequences above this were set to mute */
03248             if(seq == metaseq)
03249                 seqmute= 0;
03250 
03251             seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute);
03252         }
03253         else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
03254             if(seq->scene_sound) {
03255                 sound_mute_scene_sound(seq->scene_sound, seqmute);
03256             }
03257         }
03258     }
03259 }
03260 
03261 void seq_update_muting(Editing *ed)
03262 {
03263     if(ed) {
03264         /* mute all sounds up to current metastack list */
03265         MetaStack *ms= ed->metastack.last;
03266 
03267         if(ms)
03268             seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1);
03269         else
03270             seq_update_muting_recursive(&ed->seqbase, NULL, 0);
03271     }
03272 }
03273 
03274 static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound *sound)
03275 {
03276     Sequence *seq;
03277 
03278     for(seq=seqbasep->first; seq; seq=seq->next) {
03279         if(seq->type == SEQ_META) {
03280             seq_update_sound_recursive(scene, &seq->seqbase, sound);
03281         }
03282         else if(seq->type == SEQ_SOUND) {
03283             if(seq->scene_sound && sound == seq->sound) {
03284                 sound_update_scene_sound(seq->scene_sound, sound);
03285             }
03286         }
03287     }
03288 }
03289 
03290 void seq_update_sound(struct Scene *scene, struct bSound *sound)
03291 {
03292     if(scene->ed) {
03293         seq_update_sound_recursive(scene, &scene->ed->seqbase, sound);
03294     }
03295 }
03296 
03297 /* in cases where we done know the sequence's listbase */
03298 ListBase *seq_seqbase(ListBase *seqbase, Sequence *seq)
03299 {
03300     Sequence *iseq;
03301     ListBase *lb= NULL;
03302 
03303     for(iseq= seqbase->first; iseq; iseq= iseq->next) {
03304         if(seq==iseq) {
03305             return seqbase;
03306         }
03307         else if(iseq->seqbase.first && (lb= seq_seqbase(&iseq->seqbase, seq))) {
03308             return lb;
03309         }
03310     }
03311 
03312     return NULL;
03313 }
03314 
03315 Sequence *seq_metastrip(ListBase * seqbase, Sequence * meta, Sequence *seq)
03316 {
03317     Sequence * iseq;
03318 
03319     for(iseq = seqbase->first; iseq; iseq = iseq->next) {
03320         Sequence * rval;
03321 
03322         if (seq == iseq) {
03323             return meta;
03324         } else if(iseq->seqbase.first && 
03325             (rval = seq_metastrip(&iseq->seqbase, iseq, seq))) {
03326             return rval;
03327         }
03328     }
03329 
03330     return NULL;
03331 }
03332 
03333 int seq_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
03334 {
03335     char name[sizeof(seq_a->name)];
03336 
03337     if(seq_a->len != seq_b->len) {
03338         *error_str= "Strips must be the same length";
03339         return 0;
03340     }
03341 
03342     /* type checking, could be more advanced but disalow sound vs non-sound copy */
03343     if(seq_a->type != seq_b->type) {
03344         if(seq_a->type == SEQ_SOUND || seq_b->type == SEQ_SOUND) {
03345             *error_str= "Strips were not compatible";
03346             return 0;
03347         }
03348 
03349         /* disallow effects to swap with non-effects strips */
03350         if((seq_a->type & SEQ_EFFECT) != (seq_b->type & SEQ_EFFECT)) {
03351             *error_str= "Strips were not compatible";
03352             return 0;
03353         }
03354 
03355         if((seq_a->type & SEQ_EFFECT) && (seq_b->type & SEQ_EFFECT)) {
03356             if(get_sequence_effect_num_inputs(seq_a->type) != get_sequence_effect_num_inputs(seq_b->type)) {
03357                 *error_str= "Strips must have the same number of inputs";
03358                 return 0;
03359             }
03360         }
03361     }
03362 
03363     SWAP(Sequence, *seq_a, *seq_b);
03364 
03365     /* swap back names so animation fcurves dont get swapped */
03366     BLI_strncpy(name, seq_a->name+2, sizeof(name));
03367     BLI_strncpy(seq_a->name+2, seq_b->name+2, sizeof(seq_b->name)-2);
03368     BLI_strncpy(seq_b->name+2, name, sizeof(seq_b->name)-2);
03369 
03370     /* swap back opacity, and overlay mode */
03371     SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
03372     SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
03373 
03374 
03375     SWAP(void *, seq_a->prev, seq_b->prev);
03376     SWAP(void *, seq_a->next, seq_b->next);
03377     SWAP(int, seq_a->start, seq_b->start);
03378     SWAP(int, seq_a->startofs, seq_b->startofs);
03379     SWAP(int, seq_a->endofs, seq_b->endofs);
03380     SWAP(int, seq_a->startstill, seq_b->startstill);
03381     SWAP(int, seq_a->endstill, seq_b->endstill);
03382     SWAP(int, seq_a->machine, seq_b->machine);
03383     SWAP(int, seq_a->startdisp, seq_b->startdisp);
03384     SWAP(int, seq_a->enddisp, seq_b->enddisp);
03385 
03386     return 1;
03387 }
03388 
03389 /* XXX - hackish function needed for transforming strips! TODO - have some better solution */
03390 void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs)
03391 {
03392     char str[SEQ_NAME_MAXSTR+3];
03393     FCurve *fcu;
03394 
03395     if(scene->adt==NULL || ofs==0 || scene->adt->action==NULL)
03396         return;
03397 
03398     BLI_snprintf(str, sizeof(str), "[\"%s\"]", seq->name+2);
03399 
03400     for (fcu= scene->adt->action->curves.first; fcu; fcu= fcu->next) {
03401         if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
03402             unsigned int i;
03403             for (i = 0; i < fcu->totvert; i++) {
03404                 BezTriple *bezt= &fcu->bezt[i];
03405                 bezt->vec[0][0] += ofs;
03406                 bezt->vec[1][0] += ofs;
03407                 bezt->vec[2][0] += ofs;
03408             }
03409         }
03410     }
03411 }
03412 
03413 void seq_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst)
03414 {
03415     char str_from[SEQ_NAME_MAXSTR+3];
03416     FCurve *fcu;
03417     FCurve *fcu_last;
03418     FCurve *fcu_cpy;
03419     ListBase lb= {NULL, NULL};
03420 
03421     if(scene->adt==NULL || scene->adt->action==NULL)
03422         return;
03423 
03424     BLI_snprintf(str_from, sizeof(str_from), "[\"%s\"]", name_src);
03425 
03426     fcu_last= scene->adt->action->curves.last;
03427 
03428     for (fcu= scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu= fcu->next) {
03429         if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str_from)) {
03430             fcu_cpy= copy_fcurve(fcu);
03431             BLI_addtail(&lb, fcu_cpy);
03432         }
03433     }
03434 
03435     /* notice validate is 0, keep this because the seq may not be added to the scene yet */
03436     BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_src, name_dst, 0, 0, 0);
03437 
03438     /* add the original fcurves back */
03439     BLI_movelisttolist(&scene->adt->action->curves, &lb);
03440 }
03441 
03442 /* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */
03443 static void seq_free_animdata(Scene *scene, Sequence *seq)
03444 {
03445     char str[SEQ_NAME_MAXSTR+3];
03446     FCurve *fcu;
03447 
03448     if(scene->adt==NULL || scene->adt->action==NULL)
03449         return;
03450 
03451     BLI_snprintf(str, sizeof(str), "[\"%s\"]", seq->name+2);
03452 
03453     fcu= scene->adt->action->curves.first; 
03454 
03455     while (fcu) {
03456         if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
03457             FCurve *next_fcu = fcu->next;
03458             
03459             BLI_remlink(&scene->adt->action->curves, fcu);
03460             free_fcurve(fcu);
03461 
03462             fcu = next_fcu;
03463         } else {
03464             fcu = fcu->next;
03465         }
03466     }
03467 }
03468 
03469 
03470 Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive)
03471 {
03472     Sequence *iseq=NULL;
03473     Sequence *rseq=NULL;
03474 
03475     for (iseq=seqbase->first; iseq; iseq=iseq->next) {
03476         if (strcmp(name, iseq->name+2) == 0)
03477             return iseq;
03478         else if(recursive && (iseq->seqbase.first) && (rseq=get_seq_by_name(&iseq->seqbase, name, 1))) {
03479             return rseq;
03480         }
03481     }
03482 
03483     return NULL;
03484 }
03485 
03486 
03487 Sequence *seq_active_get(Scene *scene)
03488 {
03489     Editing *ed= seq_give_editing(scene, FALSE);
03490     if(ed==NULL) return NULL;
03491     return ed->act_seq;
03492 }
03493 
03494 void seq_active_set(Scene *scene, Sequence *seq)
03495 {
03496     Editing *ed= seq_give_editing(scene, FALSE);
03497     if(ed==NULL) return;
03498 
03499     ed->act_seq= seq;
03500 }
03501 
03502 int seq_active_pair_get(Scene *scene, Sequence **seq_act, Sequence **seq_other)
03503 {
03504     Editing *ed= seq_give_editing(scene, FALSE);
03505 
03506     *seq_act= seq_active_get(scene);
03507 
03508     if(*seq_act == NULL) {
03509         return 0;
03510     }
03511     else {
03512         Sequence *seq;
03513 
03514         *seq_other= NULL;
03515 
03516         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
03517             if(seq->flag & SELECT && (seq != (*seq_act))) {
03518                 if(*seq_other) {
03519                     return 0;
03520                 }
03521                 else {
03522                     *seq_other= seq;
03523                 }
03524             }
03525         }
03526 
03527         return (*seq_other != NULL);
03528     }
03529 }
03530 
03531 /* api like funcs for adding */
03532 
03533 void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
03534 {
03535     if(seq) {
03536         BLI_strncpy(seq->name+2, seq_load->name, sizeof(seq->name)-2);
03537         seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
03538 
03539         if(seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) {
03540             seq_load->start_frame += (seq->enddisp - seq->startdisp);
03541         }
03542 
03543         if(seq_load->flag & SEQ_LOAD_REPLACE_SEL) {
03544             seq_load->flag |= SELECT;
03545             seq_active_set(scene, seq);
03546         }
03547 
03548         if(seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
03549             if(seq->sound)
03550                 sound_cache(seq->sound);
03551         }
03552 
03553         seq_load->tot_success++;
03554     }
03555     else {
03556         seq_load->tot_error++;
03557     }
03558 }
03559 
03560 Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
03561 {
03562     Sequence *seq;
03563 
03564     seq= MEM_callocN( sizeof(Sequence), "addseq");
03565     BLI_addtail(lb, seq);
03566 
03567     *( (short *)seq->name )= ID_SEQ;
03568     seq->name[2]= 0;
03569 
03570     seq->flag= SELECT;
03571     seq->start= cfra;
03572     seq->machine= machine;
03573     seq->sat= 1.0;
03574     seq->mul= 1.0;
03575     seq->blend_opacity = 100.0;
03576     seq->volume = 1.0f;
03577     seq->pitch = 1.0f;
03578     seq->scene_sound = NULL;
03579 
03580     return seq;
03581 }
03582 
03583 /* NOTE: this function doesn't fill in image names */
03584 Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
03585 {
03586     Scene *scene= CTX_data_scene(C); /* only for active seq */
03587     Sequence *seq;
03588     Strip *strip;
03589 
03590     seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
03591     seq->type= SEQ_IMAGE;
03592     seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
03593     
03594     /* basic defaults */
03595     seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
03596 
03597     strip->len = seq->len = seq_load->len ? seq_load->len : 1;
03598     strip->us= 1;
03599     strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
03600     BLI_strncpy(strip->dir, seq_load->path, sizeof(strip->dir));
03601 
03602     seq_load_apply(scene, seq, seq_load);
03603 
03604     return seq;
03605 }
03606 
03607 #ifdef WITH_AUDASPACE
03608 Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
03609 {
03610     Main *bmain= CTX_data_main(C);
03611     Scene *scene= CTX_data_scene(C); /* only for sound */
03612     Editing *ed= seq_give_editing(scene, TRUE);
03613     bSound *sound;
03614 
03615     Sequence *seq;  /* generic strip vars */
03616     Strip *strip;
03617     StripElem *se;
03618 
03619     AUD_SoundInfo info;
03620 
03621     sound = sound_new_file(CTX_data_main(C), seq_load->path); /* handles relative paths */
03622 
03623     if (sound==NULL || sound->playback_handle == NULL) {
03624         //if(op)
03625         //  BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
03626         return NULL;
03627     }
03628 
03629     info = AUD_getInfo(sound->playback_handle);
03630 
03631     if (info.specs.channels == AUD_CHANNELS_INVALID) {
03632         sound_delete(bmain, sound);
03633         //if(op)
03634         //  BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
03635         return NULL;
03636     }
03637 
03638     seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
03639 
03640     seq->type= SEQ_SOUND;
03641     seq->sound= sound;
03642     BLI_strncpy(seq->name+2, "Sound", SEQ_NAME_MAXSTR-2);
03643     seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
03644 
03645     /* basic defaults */
03646     seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
03647     strip->len = seq->len = ceil(info.length * FPS);
03648     strip->us= 1;
03649 
03650     /* we only need 1 element to store the filename */
03651     strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
03652 
03653     BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
03654 
03655     seq->scene_sound = sound_add_scene_sound(scene, seq, seq_load->start_frame, seq_load->start_frame + strip->len, 0);
03656 
03657     calc_sequence_disp(scene, seq);
03658 
03659     /* last active name */
03660     BLI_strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR);
03661 
03662     seq_load_apply(scene, seq, seq_load);
03663 
03664     return seq;
03665 }
03666 #else // WITH_AUDASPACE
03667 Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
03668 {
03669     (void)C;
03670     (void)seqbasep;
03671     (void)seq_load;
03672     return NULL;
03673 }
03674 #endif // WITH_AUDASPACE
03675 
03676 Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
03677 {
03678     Scene *scene= CTX_data_scene(C); /* only for sound */
03679     char path[sizeof(seq_load->path)];
03680 
03681     Sequence *seq;  /* generic strip vars */
03682     Strip *strip;
03683     StripElem *se;
03684 
03685     struct anim *an;
03686 
03687     BLI_strncpy(path, seq_load->path, sizeof(path));
03688     BLI_path_abs(path, G.main->name);
03689 
03690     an = openanim(path, IB_rect, 0);
03691 
03692     if(an==NULL)
03693         return NULL;
03694 
03695     seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
03696     seq->type= SEQ_MOVIE;
03697     seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
03698 
03699     seq->anim= an;
03700     seq->anim_preseek = IMB_anim_get_preseek(an);
03701     BLI_strncpy(seq->name+2, "Movie", SEQ_NAME_MAXSTR-2);
03702     seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
03703 
03704     /* basic defaults */
03705     seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
03706     strip->len = seq->len = IMB_anim_get_duration( an, IMB_TC_RECORD_RUN );
03707     strip->us= 1;
03708 
03709     /* we only need 1 element for MOVIE strips */
03710     strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
03711 
03712     BLI_split_dirfile(seq_load->path, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name));
03713 
03714     calc_sequence_disp(scene, seq);
03715 
03716 
03717     if(seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
03718         int start_frame_back= seq_load->start_frame;
03719         seq_load->channel++;
03720 
03721         sequencer_add_sound_strip(C, seqbasep, seq_load);
03722 
03723         seq_load->start_frame= start_frame_back;
03724         seq_load->channel--;
03725     }
03726 
03727     if(seq_load->name[0] == '\0')
03728         BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name));
03729 
03730     /* can be NULL */
03731     seq_load_apply(scene, seq, seq_load);
03732 
03733     return seq;
03734 }
03735 
03736 
03737 static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence *seq, int dupe_flag)
03738 {
03739     Scene *sce_audio= scene_to ? scene_to : scene;
03740     Sequence *seqn = MEM_dupallocN(seq);
03741 
03742     seq->tmp = seqn;
03743     seqn->strip= MEM_dupallocN(seq->strip);
03744 
03745     // XXX: add F-Curve duplication stuff?
03746 
03747     if (seq->strip->crop) {
03748         seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
03749     }
03750 
03751     if (seq->strip->transform) {
03752         seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
03753     }
03754 
03755     if (seq->strip->proxy) {
03756         seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
03757         seqn->strip->proxy->anim = NULL;
03758     }
03759 
03760     if (seq->strip->color_balance) {
03761         seqn->strip->color_balance
03762             = MEM_dupallocN(seq->strip->color_balance);
03763     }
03764 
03765     if(seq->type==SEQ_META) {
03766         seqn->strip->stripdata = NULL;
03767 
03768         seqn->seqbase.first= seqn->seqbase.last= NULL;
03769         /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
03770         /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/
03771     } else if(seq->type == SEQ_SCENE) {
03772         seqn->strip->stripdata = NULL;
03773         if(seq->scene_sound)
03774             seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn);
03775     } else if(seq->type == SEQ_MOVIE) {
03776         seqn->strip->stripdata =
03777                 MEM_dupallocN(seq->strip->stripdata);
03778         seqn->anim= NULL;
03779     } else if(seq->type == SEQ_SOUND) {
03780         seqn->strip->stripdata =
03781                 MEM_dupallocN(seq->strip->stripdata);
03782         if(seq->scene_sound)
03783             seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn);
03784 
03785         seqn->sound->id.us++;
03786     } else if(seq->type == SEQ_IMAGE) {
03787         seqn->strip->stripdata =
03788                 MEM_dupallocN(seq->strip->stripdata);
03789     } else if(seq->type >= SEQ_EFFECT) {
03790         if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp;
03791         if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp;
03792         if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp;
03793 
03794         if (seq->type & SEQ_EFFECT) {
03795             struct SeqEffectHandle sh;
03796             sh = get_sequence_effect(seq);
03797             if(sh.copy)
03798                 sh.copy(seq, seqn);
03799         }
03800 
03801         seqn->strip->stripdata = NULL;
03802 
03803     } else {
03804         fprintf(stderr, "Aiiiiekkk! sequence type not "
03805                 "handled in duplicate!\nExpect a crash"
03806                         " now...\n");
03807     }
03808 
03809     if(dupe_flag & SEQ_DUPE_UNIQUE_NAME)
03810         seqbase_unique_name_recursive(&scene->ed->seqbase, seqn);
03811 
03812     if(dupe_flag & SEQ_DUPE_ANIM)
03813         seq_dupe_animdata(scene, seq->name+2, seqn->name+2);
03814 
03815     return seqn;
03816 }
03817 
03818 Sequence * seq_dupli_recursive(struct Scene *scene, struct Scene *scene_to, Sequence * seq, int dupe_flag)
03819 {
03820     Sequence * seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
03821     if (seq->type == SEQ_META) {
03822         Sequence *s;
03823         for(s= seq->seqbase.first; s; s = s->next) {
03824             Sequence *n = seq_dupli_recursive(scene, scene_to, s, dupe_flag);
03825             if (n) {
03826                 BLI_addtail(&seqn->seqbase, n);
03827             }
03828         }
03829     }
03830     return seqn;
03831 }
03832 
03833 void seqbase_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag)
03834 {
03835     Sequence *seq;
03836     Sequence *seqn = NULL;
03837     Sequence *last_seq = seq_active_get(scene);
03838 
03839     for(seq= seqbase->first; seq; seq= seq->next) {
03840         seq->tmp= NULL;
03841         if((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
03842             seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
03843             if (seqn) { /*should never fail */
03844                 if(dupe_flag & SEQ_DUPE_CONTEXT) {
03845                     seq->flag &= ~SEQ_ALLSEL;
03846                     seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
03847                 }
03848 
03849                 BLI_addtail(nseqbase, seqn);
03850                 if(seq->type==SEQ_META)
03851                     seqbase_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag);
03852 
03853                 if(dupe_flag & SEQ_DUPE_CONTEXT) {
03854                     if (seq == last_seq) {
03855                         seq_active_set(scene, seqn);
03856                     }
03857                 }
03858             }
03859         }
03860     }
03861 }