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