Changed frame numbering to only alter hashes if they are in the filename (not the...
[blender-staging.git] / source / blender / src / sequence.c
index 9f6de0fe69d1cdf7a43040b31ebfb6471f82dcfc..9f3be52af1bd7a7323b1eee2ed7b1d151591b72d 100644 (file)
@@ -1,15 +1,12 @@
 /**
  * $Id$
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,7 +22,7 @@
  *
  * Contributor(s): Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 #include <string.h>
@@ -401,8 +398,10 @@ void calc_sequence(Sequence *seq)
                                        if(seqm->enddisp > max) max= seqm->enddisp;
                                        seqm= seqm->next;
                                }
-                               seq->start= min;
-                               seq->len= max-min;
+                               seq->start= min + seq->anim_startofs;
+                               seq->len = max-min;
+                               seq->len -= seq->anim_startofs;
+                               seq->len -= seq->anim_endofs;
 
                                if(seq->strip && seq->len!=seq->strip->len) {
                                        new_tstripdata(seq);
@@ -418,22 +417,35 @@ void reload_sequence_new_file(Sequence * seq)
        char str[FILE_MAXDIR+FILE_MAXFILE];
 
        if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
-             seq->type == SEQ_HD_SOUND || seq->type == SEQ_SCENE)) {
+             seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND ||
+             seq->type == SEQ_SCENE || seq->type == SEQ_META)) {
                return;
        }
 
        new_tstripdata(seq);
 
-       if (seq->type == SEQ_IMAGE) {
-               return;
-       }
-
-       if (seq->type != SEQ_SCENE) {
+       if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
+           seq->type != SEQ_IMAGE) {
                strncpy(str, seq->strip->dir, FILE_MAXDIR-1);
                strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1);
+
+               BLI_convertstringcode(str, G.sce);
+               BLI_convertstringframe(str, G.scene->r.cfra); /* TODO - is this needed? */
+               
        }
 
-       if (seq->type == SEQ_MOVIE) {
+       if (seq->type == SEQ_IMAGE) {
+               /* Hack? */
+               int olen = MEM_allocN_len(seq->strip->stripdata) 
+                       / sizeof(struct StripElem);
+               seq->len = olen;
+               seq->len -= seq->anim_startofs;
+               seq->len -= seq->anim_endofs;
+               if (seq->len < 0) {
+                       seq->len = 0;
+               }
+               seq->strip->len = seq->len;
+       } else if (seq->type == SEQ_MOVIE) {
                if(seq->anim) IMB_free_anim(seq->anim);
                seq->anim = openanim(str, IB_rect);
 
@@ -459,8 +471,22 @@ void reload_sequence_new_file(Sequence * seq)
                        return;
                }
 
-               seq->strip->len = seq->len 
-                       = sound_hdaudio_get_duration(seq->hdaudio, FPS);
+               seq->len = sound_hdaudio_get_duration(seq->hdaudio, FPS)
+                       - seq->anim_startofs - seq->anim_endofs;
+               if (seq->len < 0) {
+                       seq->len = 0;
+               }
+               seq->strip->len = seq->len;
+       } else if (seq->type == SEQ_RAM_SOUND) {
+               seq->len = (int) ( ((float)(seq->sound->streamlen-1)/
+                                   ((float)G.scene->audio.mixrate*4.0 ))
+                                  * FPS);
+               seq->len -= seq->anim_startofs;
+               seq->len -= seq->anim_endofs;
+               if (seq->len < 0) {
+                       seq->len = 0;
+               }
+               seq->strip->len = seq->len;
        } else if (seq->type == SEQ_SCENE) {
                Scene * sce = G.main->scene.first;
                 int nr = 1;
@@ -474,6 +500,8 @@ void reload_sequence_new_file(Sequence * seq)
 
                if (sce) {
                        seq->scene = sce;
+               } else {
+                       sce = seq->scene;
                }
 
                strncpy(seq->name + 2, sce->id.name + 2, 
@@ -488,7 +516,6 @@ void reload_sequence_new_file(Sequence * seq)
                seq->strip->len = seq->len;
        }
 
-
        calc_sequence(seq);
 }
 
@@ -642,12 +669,11 @@ static void multibuf(ImBuf *ibuf, float fmul)
        int a, mul, icol;
 
        mul= (int)(256.0*fmul);
-
-       a= ibuf->x*ibuf->y;
        rt= (char *)ibuf->rect;
        rt_float = ibuf->rect_float;
 
        if (rt) {
+               a= ibuf->x*ibuf->y;
                while(a--) {
 
                        icol= (mul*rt[0])>>8;
@@ -663,6 +689,7 @@ static void multibuf(ImBuf *ibuf, float fmul)
                }
        }
        if (rt_float) {
+               a= ibuf->x*ibuf->y;
                while(a--) {
                        rt_float[0] *= fmul;
                        rt_float[1] *= fmul;
@@ -713,14 +740,9 @@ static void do_effect(int cfra, Sequence *seq, TStripElem * se)
                        return;
                }
 
-               if(se->se1->ok == STRIPELEM_META) se1= se->se1->se1;
-               else se1= se->se1;
-               
-               if(se->se2->ok == STRIPELEM_META) se2= se->se2->se1;
-               else se2= se->se2;
-               
-               if(se->se3->ok == STRIPELEM_META) se3= se->se3->se1;
-               else se3= se->se3;
+               se1= se->se1;
+               se2= se->se2;
+               se3= se->se3;
 
                if (   (se1==0 || se2==0 || se3==0)
                    || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
@@ -735,8 +757,7 @@ static void do_effect(int cfra, Sequence *seq, TStripElem * se)
                        return;
                }
 
-               if(se->se1->ok == STRIPELEM_META) se1= se->se1->se1;
-               else se1= se->se1;
+               se1= se->se1;
 
                if (se1 == 0 || se1->ibuf == 0) {
                        make_black_ibuf(se->ibuf);
@@ -755,8 +776,7 @@ static void do_effect(int cfra, Sequence *seq, TStripElem * se)
                        return;
                }
 
-               if(se->se2->ok == STRIPELEM_META) se2= se->se2->se1;
-               else se2= se->se2;
+               se2= se->se2;
 
                if (se2 == 0 || se2->ibuf == 0) {
                        make_black_ibuf(se->ibuf);
@@ -799,7 +819,7 @@ static int give_stripelem_index(Sequence *seq, int cfra)
        int nr;
 
        if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
-
+       if(seq->len == 0) return -1;
        if(seq->flag&SEQ_REVERSE_FRAMES) {      
                /*reverse frame in this sequence */
                if(cfra <= seq->start) nr= seq->len-1;
@@ -854,7 +874,8 @@ TStripElem *give_tstripelem(Sequence *seq, int cfra)
           alpha over mode...
        */
        if (seq->blend_mode != SEQ_BLEND_REPLACE ||
-           (seq->ipo && seq->ipo->curve.first && !(seq->type & SEQ_EFFECT))) {
+           (seq->ipo && seq->ipo->curve.first && (
+                   !(seq->type & SEQ_EFFECT) || !seq->seq1))) {
                Strip * s = seq->strip;
                if (cfra < seq->start) {
                        se = s->tstripdata_startstill;
@@ -998,43 +1019,6 @@ static int get_shown_sequences(
        return cnt;
 }
  
-static int get_shown_seq_from_metastrip(Sequence * seqm, int cfra,
-                                       Sequence ** seq_arr_out)
-{
-       return get_shown_sequences(&seqm->seqbase, cfra, 0, seq_arr_out);
-}
-
-void set_meta_stripdata(Sequence *seqm)
-{
-       TStripElem *se;
-       int a, cfra;
-
-       se= seqm->strip->tstripdata;
-
-       if (se == 0 && seqm->len > 0) {
-               int i;
-               se = seqm->strip->tstripdata = MEM_callocN(
-                       seqm->len*sizeof(TStripElem), "tstripelems");
-               for (i = 0; i < seqm->len; i++) {
-                       se[i].ok = STRIPELEM_META;
-               }
-       }
-
-       /* sets all ->se1 pointers in stripdata, to read the ibuf from it */
-
-       for(a=0; a<seqm->len; a++, se++) {
-               int cnt;
-               Sequence *seq_arr[MAXSEQ+1];
-
-               cfra= a+seqm->start;
-               cnt = get_shown_seq_from_metastrip(seqm, cfra, seq_arr);
-               if (cnt) {
-                       se->se1= give_tstripelem(seq_arr[cnt-1], cfra);
-               } else { 
-                       se->se1= 0;
-               }
-       }
-}
 
 /* **********************************************************************
    proxy management
@@ -1074,7 +1058,7 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
 
                frameno = tse->nr + seq->anim_startofs;
 
-               snprintf(name, PROXY_MAXFILE, "%s/%s/%d/#", dir,
+               snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir,
                         seq->strip->stripdata->name,
                         G.scene->r.size);
        } else {
@@ -1082,11 +1066,13 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
 
                frameno = tse->nr + seq->anim_startofs;
 
-               snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/#", dir,
+               snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
                         G.scene->r.size);
        }
 
-       BLI_convertstringcode(name, G.sce, frameno);
+       BLI_convertstringcode(name, G.sce);
+       BLI_convertstringframe(name, frameno);
+       
 
        strcat(name, ".jpg");
 
@@ -1143,6 +1129,9 @@ static void seq_proxy_build_frame(Sequence * seq, int cfra)
        }
 
        se = give_tstripelem(seq, cfra);
+       if (!se) {
+               return;
+       }
 
        if(se->ibuf) {
                IMB_freeImBuf(se->ibuf);
@@ -1266,7 +1255,7 @@ static StripColorBalance calc_cb(StripColorBalance * cb_)
 
        if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
                for (c = 0; c < 3; c++) {
-                       if (cb.gain[c] != 0.0) {
+                       if (cb.gamma[c] != 0.0) {
                                cb.gamma[c] = 1.0/cb.gamma[c];
                        } else {
                                cb.gamma[c] = 1000000; /* should be enough :) */
@@ -1419,6 +1408,38 @@ static void color_balance(Sequence * seq, TStripElem* se, float mul)
 
 */
 
+static int input_have_to_preprocess(Sequence * seq, TStripElem* se, int cfra)
+{
+       float mul;
+
+       if ((seq->flag & SEQ_FILTERY) || 
+           (seq->flag & SEQ_USE_CROP) ||
+           (seq->flag & SEQ_USE_TRANSFORM) ||
+           (seq->flag & SEQ_FLIPX) ||
+           (seq->flag & SEQ_FLIPY) ||
+           (seq->flag & SEQ_USE_COLOR_BALANCE) ||
+           (seq->flag & SEQ_MAKE_PREMUL) ||
+           (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
+               return TRUE;
+       }
+
+       mul = seq->mul;
+
+       if(seq->blend_mode == SEQ_BLEND_REPLACE) {
+               if (seq->ipo && seq->ipo->curve.first) {
+                       do_seq_ipo(seq, cfra);
+                       mul *= seq->facf0;
+               }
+               mul *= seq->blend_opacity / 100.0;
+       }
+
+       if (mul != 1.0) {
+               return TRUE;
+       }
+               
+       return FALSE;
+}
+
 static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
 {
        float mul;
@@ -1620,41 +1641,52 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
                              int build_proxy_run)
 {
        char name[FILE_MAXDIR+FILE_MAXFILE];
+       int use_limiter = TRUE;
 
-
-       if (seq->type != SEQ_META) {
-               test_and_auto_discard_ibuf(se);
-               test_and_auto_discard_ibuf_stills(seq->strip);
-       }
+       test_and_auto_discard_ibuf(se);
+       test_and_auto_discard_ibuf_stills(seq->strip);
 
        if(seq->type == SEQ_META) {
-               if(seq->seqbase.first) {
-                       if(cfra < seq->start) {
-                               do_build_seq_array_recursively(
-                                       &seq->seqbase, 
-                                       seq->start, 0);
-                       } else if(cfra > seq->start + seq->len - 1) {
-                               do_build_seq_array_recursively(
-                                       &seq->seqbase, 
-                                       seq->start + seq->len - 1, 0);
-                       } else {
-                               do_build_seq_array_recursively(
-                                       &seq->seqbase, 
-                                       cfra, 0);
+               TStripElem * meta_se = 0;
+               use_limiter = FALSE;
+
+               if (!build_proxy_run && se->ibuf == 0) {
+                       se->ibuf = seq_proxy_fetch(seq, cfra);
+                       if (se->ibuf) {
+                               use_limiter = TRUE;
                        }
                }
 
-               se->ok = STRIPELEM_META;
-               if(se->se1 == 0) set_meta_stripdata(seq);
-               if(se->se1) {
-                       if(se->ibuf) {
-                               IMB_freeImBuf(se->ibuf);
-                       }
-                       se->ibuf = se->se1->ibuf_comp;
-                       if(se->ibuf) {
+               if(!se->ibuf && seq->seqbase.first) {
+                       meta_se = do_build_seq_array_recursively(
+                               &seq->seqbase, seq->start + se->nr, 0);
+               }
+
+               se->ok = STRIPELEM_OK;
+
+               if(!se->ibuf && meta_se) {
+                       se->ibuf = meta_se->ibuf_comp;
+                       if(se->ibuf &&
+                          (!input_have_to_preprocess(seq, se, cfra) ||
+                           build_proxy_run)) {
                                IMB_refImBuf(se->ibuf);
+                               if (build_proxy_run) {
+                                       IMB_cache_limiter_unref(se->ibuf);
+                               }
+                       } else if (se->ibuf) {
+                               struct ImBuf * i = IMB_dupImBuf(se->ibuf);
+
+                               IMB_cache_limiter_unref(se->ibuf);
+
+                               se->ibuf = i;
+
+                               use_limiter = TRUE;
                        }
                }
+
+               if (use_limiter) {
+                       input_preprocess(seq, se, cfra);
+               }
        } else if(seq->type & SEQ_EFFECT) {
                /* should the effect be recalculated? */
                
@@ -1678,7 +1710,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
                        
                        strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
                        strncat(name, s_elem->name, FILE_MAXFILE);
-                       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+                       BLI_convertstringcode(name, G.sce);
+                       BLI_convertstringframe(name, G.scene->r.cfra);
                        if (!build_proxy_run) {
                                se->ibuf = seq_proxy_fetch(seq, cfra);
                        }
@@ -1707,7 +1740,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
                                if(seq->anim==0) {
                                        strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
                                        strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
-                                       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+                                       BLI_convertstringcode(name, G.sce);
+                                       BLI_convertstringframe(name, G.scene->r.cfra);
                                
                                        seq->anim = openanim(name, IB_rect);
                                }
@@ -1818,7 +1852,7 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
                }       
        }
        if (!build_proxy_run) {
-               if (se->ibuf && seq->type != SEQ_META) {
+               if (se->ibuf && use_limiter) {
                        IMB_cache_limiter_insert(se->ibuf);
                        IMB_cache_limiter_ref(se->ibuf);
                        IMB_cache_limiter_touch(se->ibuf);
@@ -2044,6 +2078,10 @@ static TStripElem* do_build_seq_array_recursively(
 
        se = give_tstripelem(seq_arr[count - 1], cfra);
 
+       if (!se) {
+               return 0;
+       }
+
        test_and_auto_discard_ibuf(se);
 
        if (se->ibuf_comp != 0) {