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